CLI reference
Exit codes
Heddle follows BSD sysexits.h. Classification is keyed on
typed error kinds — never on message text — and each pairing is pinned
by a regression test in the binary. If you are driving the CLI
unattended, this page is the shortest thing on the site worth reading
in full.
The table
| Code | Symbol | Meaning |
|---|---|---|
0 | Ok | Success. |
64 | Usage | Invalid CLI args, unknown subcommand, malformed flag (EX_USAGE). |
65 | DataErr | Well-formed input, semantically rejected (EX_DATAERR). Includes corrupted or undecodable repository state. |
73 | CantCreat | Output file refused — exists, unwritable, or state dir uncreatable. |
74 | IoErr | Generic IO failure during read/write (EX_IOERR). The default fallback. |
75 | TempFail | Transient failure; safe to retry with the same args (EX_TEMPFAIL). |
76 | Protocol | Remote rejected the payload; retrying without changing inputs will fail the same way (EX_PROTOCOL). |
77 | NoPerm | Operation refused for permission reasons (EX_NOPERM). |
78 | Config | Configuration or a required precondition is missing, ambiguous, or invalid — not just config-file errors. Covers unconfigured remotes and upstreams, a missing repository, and conflicting identity. |
2 is reserved for set -e and unhandled panics.
Heddle never emits it intentionally — it surfaces naturally.
The retry rule
75TempFail — retry with the same args. This is the only one. A hosted rate limit arrives here too, so backoff belongs in your agent.76Protocol — the inputs are the problem, not the network. Don't loop.78Config — a precondition is missing. Print the missing setting rather than retrying.65DataErr — semantic rejection of well-formed input. No retry with the same inputs will help.74IoErr — the catch-all.64Usage — you spelled something wrong. An unknown subcommand or a flag the command does not have lands here, which is what every fabricated command in a doc produces.
Commands that declare their codes
Most commands have not been swept yet. Those implicitly contract to 0 on success and an unspecified non-zero on failure — treat
them as “may return any code above” until their contract entry declares
otherwise. These 8 do declare, and the declarations are
rendered here straight from the command catalog:
heddle init0ok73cannot create state directory78workspace config invalid
heddle status0ok74io reading workspace state
heddle verify0verified clean65verification reports blocked state74io reading state
heddle sync git0ok75remote unreachable; safe to retry76remote rejected payload
heddle commit0Git checkpoint written or already current65repository mode or worktree preflight refused74io while writing Git state
heddle import git0ok65malformed git repo or unimportable refs74io reading git refs
heddle push0ok75remote unreachable; safe to retry76remote rejected payload; do not retry without changing inputs78no upstream configured
heddle pull0ok75remote unreachable; safe to retry76upstream protocol error78no upstream configured
Contract stability
The CLI's cargo version is the JSON contract version. Pin a heddle-cli version constraint and the catalogued output
shapes — output_kind, declared discriminators, exit_codes — hold for that minor. Breaking changes to any
catalogued output bump the minor pre-1.0 and the major after; additive
changes, including a new optional exit code, bump the patch.
Ground truth: heddle 0.12.0. See also the JSON output contract, where the error envelope that carries the code lives.