Skip to content

Exit codes

Muhammet Şafak edited this page May 27, 2026 · 1 revision

--fail-on and exit codes

General exit codes

Code Meaning
0 Success.
1 Error: pipeline failure (git error, provider error, parse failure, guard abort, config invalid, …) OR --fail-on threshold reached.

There is no distinction between "pipeline failed" and "--fail-on matched" at the exit-code level — both exit 1. Stderr disambiguates: pipeline failures print the underlying error; --fail-on matches print <N> finding(s) at or above '<severity>' severity (or 'any').

The --fail-on flag

Maps the highest severity in the findings to an exit code. Use in CI to fail the build when a review surfaces something serious.

--fail-on=<critical|high|medium|low|info|any|none>

Case-insensitive. Whitespace tolerated.

Values

Value Meaning
"" (default) Off. Pipeline failures still exit 1; findings do not.
none Synonymous with off.
any Any finding at any severity fails.
critical Fail when one or more findings have severity critical.
high Fail at high OR critical.
medium Fail at medium, high, OR critical.
low Fail at low, medium, high, OR critical.
info Fail on any finding (since info is the lowest level). Equivalent to any.

Anything else is a parse error before the review fires: invalid --fail-on value "X" (expected: critical, high, medium, low, info, any, none).

Severity ordering

Highest → lowest:

critical > high > medium > low > info

--fail-on=high means "fail on high or worse". See Severity for the per-level definitions.

Behavior on graceful degrade

When the LLM produces unparseable JSON (and the one-shot retry also fails), CommitBrief degrades to markdown rendering and the findings list is nil. In this case --fail-on is intentionally skipped and stderr prints:

ℹ --fail-on skipped: LLM produced unparseable output, no findings to evaluate.

Rationale: failing CI on an unparseable response would be worse than letting the run succeed and surfacing the markdown text — the user still sees the review content, and a flaky model invocation should not break the build on its own.

Examples

# CI block on any critical-or-worse finding.
commitbrief --staged --fail-on=critical

# Strictest possible: any finding at all fails.
commitbrief --staged --fail-on=any

# Off — surfacing findings is informational, never fails CI.
commitbrief --staged
commitbrief --staged --fail-on=none      # explicit form

Common CI patterns

GitHub Actions step:

- name: Review staged changes
  run: commitbrief --staged --fail-on=critical --no-cost-check

GitLab CI:

review:
  script:
    - commitbrief --staged --fail-on=high --quiet --json --output review.json
  artifacts:
    paths: [review.json]

Pre-commit (via commitbrief install-hook):

The generated pre-commit hook embeds --fail-on=critical --quiet --no-cost-check already — see Install-hook command.

Interaction with other guards

Guard Exit code on abort
.commitbrief/ pre-send guard (ADR-0007) 1 with aborted by pre-send guard.
Secret scanner 1 with aborted: pre-send secret scanner (or non-interactive variant).
Cost preflight 1 with aborted: cost preflight (or non-interactive variant).
--fail-on 1 with the count + severity label.

All of these are pipeline-level exit-1 outcomes; they happen independently of --fail-on (which only evaluates after a successful provider call).

See also

Clone this wiki locally