Skip to content

Exit codes

shipped 1.0.0
CodeMeaning
0success
1generic error
2configuration error
3missing dependency
4remote error
5refused by a safety guard
6aborted by the user

5 is the one to gate on. It means a guard refused:

  • a protected environment without --force,
  • an upward effect with no committed source,
  • a page that changed on the target since cwp last saw it,
  • a pre-push hook that exited non-zero,
  • a pre-pull snapshot cwp could not take.

6 means cwp could not ask. A command that needs a confirmation and has no terminal (under --json, in CI, in a pipeline) refuses rather than assuming yes.

--dry-run does not always exit 0. The refusals run in a dry run and the confirmations do not, so cwp push prod --dry-run on a protected environment still exits 5 rather than printing a plan for a write it would never permit. A dry run that stopped refusing would be describing a different command.

Signals, and the three pass-throughs

A pass-through whose program was killed by a signal reports the shell’s 128 + signum. Interrupting cwp logs -f with Ctrl-C exits 130, which is how that command normally ends rather than a failure.

cwp wp, cwp shell and cwp logs forward the other program’s exit code verbatim, so a code from the table above may there mean whatever that program meant by it. The refusals of cwp itself still use these codes, and all of them happen before the program starts.

The output contract is the full contract: which stream carries what, and what is in the envelope.