Incomplete-result policy

Decide how missing analysis affects the gate without mistaking an unavailable result for a clean one.

Default behavior

A finding and a failed analysis are different

A completed check can report a finding: the analyzer ran and found a problem. An incomplete check means it could not produce the required analysis, for example because it could not parse selected input, an engine failed, or an online service was unavailable.

failOnIncomplete defaults to true. It makes an enabled incomplete check blocking unless the result has a more specific policy, such as the OSV outage setting.

Setting a check’s severity to warn only changes how its findings affect the gate. It does not automatically make an analysis failure non-blocking. Likewise, a check that is disabled or not applicable is different from a check that tried to run and failed.

.zedbeerc.jsonc · keep incomplete checks blocking
{
  "schemaVersion": 1,
  "profile": "recommended",
  "failOnIncomplete": true
}
Specific versus general policy

Keep an OSV exception separate from other failures

For a recognized OSV availability failure, checks.vulnerabilities.onUnavailable supplies the result’s specific block or warn disposition. That explicit disposition takes precedence over the general failOnIncomplete setting.

The example enables vulnerability analysis and allows a supported OSV outage to be non-blocking while retaining the default for other incomplete checks. It does not downgrade completed vulnerability findings.

The reverse matters too: onUnavailable: "block" still blocks a supported outage even if failOnIncomplete is false. Malformed lockfiles, rejected responses, and other analysis errors are not outage exceptions; they use the normal incomplete-result handling when no specific disposition is supplied.

Review supported OSV outage cases
Allow OSV outages, retain other incomplete blockers
{
  "schemaVersion": 1,
  "profile": "recommended",
  "failOnIncomplete": true,
  "checks": {
    "vulnerabilities": {
      "severity": "error",
      "onUnavailable": "warn"
    }
  }
}
Incomplete exit codes

Which result wins when several things happen?

Swarm first checks for a blocking incomplete result, then for blocking findings. A blocking incomplete result takes priority over a completed check’s findings, so a scan can report findings and still exit with 2.

Scan policy outcome examples
ScenarioPolicyExit code
All enabled checks complete; no blocking findingsDefault0
A completed check has an attributable error finding; no blocking incomplete checksCheck severity: error1
An enabled check is incomplete, with no specific dispositionfailOnIncomplete: true2
A warn-severity check is incomplete, with no specific dispositionfailOnIncomplete: true2
An incomplete check has no specific disposition and nothing else blocksfailOnIncomplete: false0, with the incomplete check still reported
The same non-blocking incomplete check plus an attributable error findingfailOnIncomplete: false1
Supported OSV outage and nothing else blocksfailOnIncomplete: true; onUnavailable: warn0, with the outage still reported
Supported OSV outagefailOnIncomplete: false; onUnavailable: block2
Invalid vulnerability input or response, without a specific dispositionfailOnIncomplete: true; onUnavailable: warn2

These examples describe check-result evaluation. failOnIncomplete: false is not a universal ignore-errors switch: invalid configuration, unavailable comparison snapshots, and other failures that prevent a trustworthy scan can still return an error.

Exit code 0 does not always mean every check completed.

If policy allows incomplete results, a scan can proceed while still reporting missing analysis. Read the incomplete-check details in the complete report, not only the process exit code.

Choose deliberately

Make the narrowest exception your workflow needs

Leaving failOnIncomplete: true keeps missing required analysis visible as a failure. If your intended exception is only an OSV outage, use its dedicated setting rather than making every otherwise-unspecified incomplete check non-blocking.

Setting failOnIncomplete: false changes the default for incomplete checks that lack a specific disposition. It does not suppress their diagnostics or repair the missing analysis. Agree on when those checks will be rerun before relying on that policy.

Stage policy edits for local scans. For CI, commit and push them on the branch being checked. A file edited after CI checkout does not change the committed policy used by a base-mode scan.

When policy updates take effect
Inspect the staged policy
git add .zedbeerc.jsonc
npx zedbee checks --format json
Troubleshooting and CI

Resolve the diagnostic and keep the exit status

Read the incomplete check’s code, path, and remediation. Fix invalid or unsupported input, restore missing Git history, investigate an engine failure, or retry after service recovery as appropriate. zedbee doctor helps inspect the environment without running a scan.

For local scans, stage corrected files before retrying. For CI, commit the correction and run against the updated commit. Keep the report even when the job fails so the diagnostic remains available.

Do not append || true or let a later successful command overwrite the scan’s exit status when the scan is intended to gate a commit or merge. Preserve the policy decision and configure artifact retention separately.

Use the CI example that preserves exit status
Diagnose and retain the complete report
npx zedbee doctor
npx zedbee scan --format json > zedbee-report.json