# Exit codes

> What every CommitBrief command returns and why — the two exit codes the CLI defines, and what determines which one you get.

CommitBrief docs · v1.x · Reference

Canonical URL: https://commitbrief.com/docs/1.x/exit-codes/

---

CommitBrief defines exactly **two** exit codes. There is no larger
table of numbered failure reasons to memorize — the distinction that
matters is always "did it succeed" vs. "did anything go wrong,"
including a gate you asked it to enforce.

| Code | Meaning |
|---|---|
| `0` | Success. Includes an empty diff, `--gen-man` completing, and a `--fail-on` threshold that was *not* breached. |
| `1` | Any error. Includes a breached `--fail-on` threshold, a breached `guard` policy, a `doctor` probe failure, a provider error, an aborted pre-send guard or cost preflight, an invalid flag value, a missing git repository, and `remote pr`'s "too volatile to retry" case. |

Cobra (the CLI framework CommitBrief is built on) catches an unknown
flag or malformed argument at parse time, before your command's own
logic runs — but CommitBrief wraps that error in the same `os.Exit(1)`
call as everything else, so it's still exit code `1`, not a distinct
number. In every case, CommitBrief only ever returns `0` or `1`.

## `--fail-on`

[`--fail-on=<severity>`](/docs/1.x/severity#the---fail-on-flag) is
evaluated against the **actionable** finding set — after
[baseline and suppression](/docs/1.x/signal-control) have already
removed what they're going to remove. A threshold that is met or
exceeded by at least one remaining finding produces exit `1`; anything
else, including no findings at all, is `0`.

If the provider's response can't be parsed into structured findings,
`--fail-on` degrades gracefully rather than failing the run outright —
see [Graceful degrade behavior](/docs/1.x/severity#graceful-degrade-behavior)
for the exact stderr message.

`--fail-on` is ignored (with a warning) in `remote pr`'s posting mode —
posting a PR comment isn't a gate, so there's nothing for it to enforce
there.

## `--min-severity`

[`--min-severity`](/docs/1.x/severity#display-filter----min-severity)
only changes what is *displayed*. It never touches the exit code, and
it never touches what `--fail-on` or `--json` see — a finding hidden
from the terminal by `--min-severity` can still trip `--fail-on` or
appear in `--json`.

## `commitbrief guard`

[`guard`](/docs/1.x/policy-gate) exits `0` when the policy passes and
non-zero when it's blocked. Critically, a **missing or malformed
policy file, or a review it cannot parse, also counts as blocked** —
the gate fails closed rather than passing when it cannot prove the
change is within policy. `guard --json` emits a machine-readable
verdict (`passed`, `counts`, `total`, `violations`) alongside the same
exit code.

## Using this in a script

Because there are only two codes, a script never needs to branch on a
specific number — a plain `if`/`&&` on the command is enough:

```sh
if commitbrief diff origin/main...HEAD --fail-on=critical; then
  echo "clean"
else
  echo "blocked" >&2
  exit 1
fi
```

## See also

- [Severity and CI gating](/docs/1.x/severity) — the full `--fail-on`
  value table and CI recipes.
- [Policy gate](/docs/1.x/policy-gate) — `guard`'s policy file and
  `--json` verdict shape.
- [Signal control](/docs/1.x/signal-control) — baseline and
  suppression, applied before any gate sees a finding.