Agent Wranglers

DSK-20Recommended

Exit with zero only when the command did everything it was asked

Exit 0 only when every action succeeded, and exit with a code from 1 to 125 on any failure. Document each code in the help text and keep its meaning fixed.

How to do it

Scripts, CI jobs and agents read the exit code, not the text. A tool that prints an error and exits 0 lets a broken deploy carry on. POSIX defines 0 as success and leaves 126, 127 and codes above 128 to the shell. Keep 2 for wrong usage, as many tools do. Give each failure a meaning a caller can act on, such as "not found" or "try again". Keep error types stable asks the same of APIs. On Ctrl+C, stop cleanly and exit 130. A partial success is a failure, with the details in the output.

Examples

Python example

import sys

EXIT_OK, EXIT_FAILED, EXIT_USAGE, EXIT_NOT_FOUND, EXIT_RETRY = 0, 1, 2, 3, 4

def main() -> int:
    try:
        invoice = client.fetch(args.invoice_id)
    except NotFound:
        print(f"invoice {args.invoice_id} not found", file=sys.stderr)
        return EXIT_NOT_FOUND
    except ServiceUnavailable:
        print("service unavailable, try again later", file=sys.stderr)
        return EXIT_RETRY
    print(invoice.number)
    return EXIT_OK

if __name__ == "__main__":
    sys.exit(main())

Go example

const (
	exitOK       = 0
	exitFailed   = 1
	exitUsage    = 2
	exitNotFound = 3
	exitRetry    = 4
)

func main() {
	invoice, err := client.Fetch(invoiceID)
	switch {
	case errors.Is(err, ErrNotFound):
		fmt.Fprintf(os.Stderr, "invoice %s not found\n", invoiceID)
		os.Exit(exitNotFound)
	case err != nil:
		fmt.Fprintln(os.Stderr, "service unavailable, try again later")
		os.Exit(exitRetry)
	}
	fmt.Println(invoice.Number)
}

How to check

A test runs each command with a missing file, a wrong flag and a server that answers 500. Each run exits with its documented non-zero code. A successful run exits 0, and the help text lists every code.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/desktop-apps/command-line-tools/exit-codes">Agent Wranglers desktop apps, extensions and CLIs playbook</a>. In code you write, add a comment next to it with the same link.