P4: Fail Fast with Actionable Errors
Definition
CLI tools MUST detect invalid state early, exit with a structured error, and tell the caller three things: what failed, why, and what to do next. An error that says "operation failed" gives an agent nothing to act on.
Why Agents Need It
Agents operate in a retry loop: attempt, observe, decide. When an error is vague or unstructured (a bare stack trace, a one-word failure, a mixed-channel splurge), the agent cannot tell whether to retry, re-authenticate, fix configuration, or escalate to the user. Distinct exit codes paired with this standard's published mapping let the agent act correctly on the first read. The difference between exit code 77 (re-authenticate) and exit code 78 (fix config) determines whether the agent retries OAuth or asks the user to check their config file. Getting that wrong wastes entire conversation turns.
Codes 77 and 78 follow BSD sysexits.h (EX_NOPERM, EX_CONFIG). Most CLIs today do not distinguish auth from config
errors at the exit-code layer; this standard adopts sysexits.h numbering so agents can disambiguate.
Requirements
Evidence
Cli::try_parse()inmain(), notCli::parse().- Error enum with
#[derive(Error)]and distinct variants for config, auth, and command errors. exit_code()method on the error type returning variant-specific codes.kind()method returning a machine-readable string for JSON serialization.run()function returningResult<(), AppError>, not callingprocess::exit()internally.- Error messages containing remediation steps ("run X" or "set Y") alongside the cause.
Anti-Patterns
Cli::parse()anywhere in the codebase, because it silently prevents JSON error output.process::exit()in library code or command handlers. Onlymain()(and signal/panic handlers it installs) may call it, after all error handling.- A single catch-all error variant that maps everything to exit code 1.
- Error messages that state the symptom without the cause or fix ("Error: request failed").
- Panics (
unwrap(),expect()) on recoverable errors in production code paths.
Measured by audit IDs p4-bad-args, p4-process-exit, p4-unwrap, p4-exit-codes. Run anc audit --principle 4 .
against the CLI under test to see each.