Skip to content

Exit codes

Exit codes are the API. Every command returns exactly one of three codes, and every command is CI-composable on that basis — human output is presentation, the exit code is the verdict.

CodeMeaning
0Clean — no findings at or above --threshold (default: high)
1Findings at or above --threshold
2Execution error — the run itself failed; never treat as clean

--threshold accepts severity names (low/med/medium/high/critical) or grade letters (B/C/D/F). A is rejected — grade A means zero findings, which exit 0 already expresses. Findings below the threshold are still reported in output; they just don’t flip the exit code.

Command012 (examples)
checkNo queried/bundled package resolves anywhere in the treeAt least one match in the resolved treeNo/unparseable lockfile · bad query · unknown incident id · lockfile not in git history (--history)
auditNo findings at/above thresholdFindings at/above thresholdUnparseable lockfile · lockfile missing at --diff ref · --diff + --deep together · invalid --threshold · integrity mismatch on a fetched tarball · network attempt under --offline · vendored advisory data older than --max-advisory-age
driftNo anomalies at/above thresholdAnomalies at/above thresholdUnknown --base ref · lockfile missing at base ref · unparseable lockfile
scanNo findings at/above thresholdFindings at/above thresholdArtifact not found/unreadable · docker save failed
secretsNo findings at/above thresholdFindings at/above thresholdExecution error

Note that check’s exit code ignores --threshold semantics in spirit — a hit is a hit — while the scoring commands (audit, drift, scan, secrets) compare finding severities against the threshold.

The if-form reads naturally because exit 0 is “clean”:

Terminal window
if npx lockwarden check node-ipc@9.1.6 --ci; then
echo "not affected"
else
echo "affected or errored — see above"
fi

Three-way handling when “hit” and “broken run” must diverge (they should — an unparseable lockfile during an incident is not good news):

Terminal window
npx lockwarden check --incident node-ipc-may26 --ci
case $? in
0) echo "clean" ;;
1) echo "HIT — escalate" ;;
2) echo "check failed to run — investigate manually" ;;
esac

Chain gates so any failure stops the pipeline (set -e respects both 1 and 2):

Terminal window
set -e
npx lockwarden audit --diff "$BASE_SHA" --ci
npx lockwarden drift --base "$BASE_SHA" --ci

Run the gate but never break the build (report-only mode) while still failing on broken runs:

Terminal window
npx lockwarden audit --diff "$BASE_SHA" --ci || [ $? -eq 1 ]

Every major CI fails a step on non-zero exit — no plugin or wrapper is needed. The GitHub Action simply surfaces the same codes: exit 1 fails the check, exit 2 errors it. Whether a failed check blocks the merge is your branch protection policy — lockwarden detects, it never enforces.

Complete pipeline examples: CI recipes.