Skip to content

bug: overrides --fail-on exit code inconsistent with scan path #784

Description

@luojiyin1987

Problem

There are two parallel severity ranking definitions that are inconsistent:

1. severityOrder in src/constants.ts:3

export const severityOrder: Record<SeverityLabel, number> = {
  none: 0, low: 1, medium: 2, high: 3, critical: 4, unknown: 1
};

Used by: scan path (src/index.ts:710), multi-folder scan (src/scan/multi-folder-scan.ts:175), create-pr (src/utils/create-pr.ts:45), and minSeverity filtering (src/output/finding-display.ts:8).

2. Local rank in src/cli/overrides.ts:87

const rank: Record<string, number> = { info: 0, low: 1, medium: 2, high: 3, critical: 4 };

Used only by: standalone cve-lite overrides --fail-on command.

Inconsistencies

Key severityOrder (constants.ts) rank (overrides.ts) Issue
info missing 0 Not in SeverityLabel; treated as valid threshold in overrides, silently ignored in scan
none 0 missing (?? 0) Same de facto value (0), but implicit in overrides
unknown 1 (same as low) missing (?? 0) Bug: override finding with unknown severity won't trigger --fail-on low

Concrete risk

If an override finding has severity unknown, the standalone cve-lite overrides --fail-on low path evaluates it as rank 0 (via ?? 0), which is below the low threshold (1). But the scan path treats unknown as rank 1 (same as low). This means:

  • cve-lite overrides --fail-on low — finding with unknown severity does NOT trigger exit code 1
  • cve-lite scan --fail-on low --check-overrides — same finding DOES trigger exit code 1 (uses severityOrder)

This is an exit-code inconsistency, so it can affect CI gating — a pipeline gated on --fail-on low would pass for standalone overrides but fail for the same check via scan --check-overrides.

Suggested approach

  1. Make standalone cve-lite overrides --fail-on reuse the same severity threshold logic as scan path (normalizeSeverity + severityOrder).
  2. Treat unknown consistently with severityOrder (unknown: 1, same as low), unless maintainers decide otherwise.
  3. Decide separately whether info should become a real severity type.

Open questions

  • Should info be added to the SeverityLabel union type, or should overrides use its own abstraction?
  • Is unknown: 1 (same as low) the correct default? Should it be different?

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions