Skip to main content
Every 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:
In --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.
Ctrl-C does not cancel the run. The CLI only polls for status — the run itself keeps executing (and billing, where it applies) on the server whether or not the CLI is still attached. Reattach with testsprite test wait <run-id>, or actually stop it with testsprite test cancel <run-id>.
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-readable code 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:
In text mode, the CLI prints 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, or null (not yet executed or not applicable).

Run source

The source 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. For PRECONDITION_FAILED, re-fetch codeVersion first, then retry.
  • Exit 10 (UNAVAILABLE) — retry with exponential backoff (capped at 4 retries automatically by the CLI).
  • Exit 11 (RATE_LIMITED) — wait for the Retry-After duration before retrying (cap 3 retries automatically).
Non-retriable codes — fix the root cause before retrying:
  • 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.
Reuse --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