testsprite command returns a stable exit code. Agents and CI pipelines branch on the exit code; the JSON error envelope supplies the machine-readable detail. Exit codes and error codes will not change within a major version.
Exit codes
The
--help and --version flags always exit 0. Flag-parse errors exit 5.Signals & pipes
129, 130, and 143 are the conventional 128 + signal codes for SIGHUP, SIGINT, and SIGTERM respectively. When a signal lands while the CLI is polling a run (--wait, test wait, test flaky), it detaches gracefully: stdout gets the same partial object a --timeout would print ({ "runId": "...", "status": "running" }), and stderr names the run and both ways forward:
--output json mode, stderr instead carries an INTERRUPTED error envelope with details.signal — deliberately outside the error-code table below, since no request failed. Outside a polling wait (at a prompt, mid-listing), the CLI prints a one-line generic reminder and exits with the same codes. A second signal exits immediately.
Separately, if stdout is piped into a reader that closes early — testsprite test list --output json | head -n 1 — the next write raises EPIPE. The CLI swallows it silently and exits 0, the conventional outcome for “the reader went away,” not a failure.
Error codes
Every error response carries a machine-readablecode string alongside the HTTP status and CLI exit code.
Error output
Every command emits the same JSON error envelope when something goes wrong, regardless of--output mode:
message and nextAction as human-readable lines. For AUTH_FORBIDDEN, text mode also prints the required scope list and the granted scope list so you can immediately identify what’s missing.
Test and run status
Test status
The test-level normalized status reflects the outcome of the most recent completed run. The CLI exposes 9 values.Run status
An individual run has 6 possible statuses. Terminal statuses are the four that produce a final verdict.Step status
Each step in a run is: passed, failed, ornull (not yet executed or not applicable).
Run source
Thesource field on a run identifies which surface triggered it.
Retrying safely
Retriable codes — use an idempotency key so retries are deduplicated server-side:- Exit
6(CONFLICT) — retry once after 1 second. ForPRECONDITION_FAILED, re-fetchcodeVersionfirst, then retry. - Exit
10(UNAVAILABLE) — retry with exponential backoff (capped at 4 retries automatically by the CLI). - Exit
11(RATE_LIMITED) — wait for theRetry-Afterduration before retrying (cap 3 retries automatically).
- Exit
4(NOT_FOUND) — verify the ID. - Exit
5(VALIDATION_ERROR,PAYLOAD_TOO_LARGE) — fix the input. - Exit
12(INSUFFICIENT_CREDITS) — top up your balance.
--idempotency-key on write commands when retrying manually so the backend dedupes server-side.
Safe retries
How idempotency keys make manual retries safe
Where to Go Next
Command Reference
Every command and flag in one place
Configuration
Environment variables, profiles, and the JSON output contract
CI/CD Integration
Gate pipelines on exit codes
Running Tests
Triggering runs and handling results