Skip to content

Exit codes

Every command follows the same contract, so scripts and CI can branch on the result without parsing output:

CodeMeaning
0Success. The command did what it set out to do.
1Error. Something failed — a bad config, a connection failure, a policy violation, or a declined apply / destroy / force-unlock.
2Changes present. Only from the opt-in checks: plan / drift with --detailed-exitcode, and fmt --check. Never returned without opting in.
130Cancelled with Ctrl-C (SIGINT).

Two things worth calling out for automation

Section titled “Two things worth calling out for automation”

plan and drift exit 0 by default, even when there are changes

Section titled “plan and drift exit 0 by default, even when there are changes”

The 2 signal is opt-in via --detailed-exitcode, so nschema plan && nschema apply and pipelines that fail on any non-zero code work as expected. Add the flag only where you want to gate on “would this change anything?”:

Terminal window
nschema plan --detailed-exitcode # exit 2 if the schema would change
nschema drift --detailed-exitcode # exit 2 if the database has drifted

Answering anything but yes, or running with no interactive terminal (CI, a container) and without --auto-approve, makes no changes and exits non-zero — so a forgotten --auto-approve fails the step instead of looking like a successful no-op. Always pass --auto-approve for unattended runs.

See Running in CI for putting these to work.