Skip to main content
How agent-guardian signals failure. CLI exit codes drive CI gates; the LLMError hierarchy lets SDK callers branch on transport / auth / quota faults without parsing strings.

When to use this

  • You’re writing a CI job and need to know which exit codes a scan step can return.
  • You’re wrapping the SDK and need a clean try / except taxonomy for provider failures.
  • You’re debugging a scan that exited non-zero and want to know what the number means.

CLI exit codes

Defined in src/agent_guardian/cli.py. Every top-level command exits with one of these.

How CI gates branch on this

Always branch on the exit code rather than parsing stdout: the exit contract is stable; the human-readable lines are not.

Sample exit-code triggers

A few concrete shapes:

LLM provider exception taxonomy

Defined in src/agent_guardian/llm/errors.py. Every provider client maps HTTP / SDK errors into one of these so the rest of the framework can decide whether to retry, surface to the operator, or abort the scan without caring about the underlying transport.
All seven are exported from agent_guardian (the top-level package).

Catching them in your code

The bundled agent_guardian.llm.retry helpers honour this taxonomy: they retry the transient classes (LLMRateLimitError, LLMTimeoutError, LLMTransientError), respect retry_after, and fail fast on the rest.

Mapping back to a CLI exit code

When the CLI hits a provider error during a scan, it surfaces it as EXIT_LLM_PROVIDER (4) after pre-scan validation, or lets the swarm’s internal retry policy absorb transients. The operator always sees:
on stderr.

How to interpret the result

  • 0 / 1 are the only exit codes a healthy scan should produce. Anything else means the scan didn’t run to completion.
  • 2 / 3 / 4 are operator-fixable: bad config, dead endpoint, missing key. Surface the underlying message on stderr — the CLI tells you which.
  • 5 is rare and means an agent tried to escape the sandbox. File an issue with the scan transcript.
  • 130 is just Ctrl-C — no action needed.
  • In Python code, prefer catching specific LLMError subclasses over the base — your retry policy depends on the distinction.

Next step