Skip to main content
Agents and CI branch on the exit code; the JSON error envelope adds detail. Exit codes and error codes won’t change within a major version. --help and --version exit 0.

Exit codes

Wait timeout (exit 7)

Before exiting, the CLI still prints { "runId": "...", "status": "running" } to stdout.
  • Ordinary run: resume with testsprite test wait <run-id>.
  • Run that owns its tunnel (automatic, or --local): the timeout cancels it by default and closes the tunnel, so start a new run with a longer --timeout. Cancellation is best-effort and the run may already be billed.
  • Local batch: each run has its own timeout. A timeout (7) outranks failures (1) but not auth (3), conflict (6), transport (10), rate-limit (11) or credit (12) errors.

Interrupts and pipes

129, 130 and 143 are 128 + signal. A signal while polling an ordinary run (--wait, test wait, test flaky), or a --local run adopted with --tunnel-client, detaches: the run keeps executing and billing, stdout gets the partial running object, and stderr names the run:
A run on a tunnel this command opened (automatic or --local) is cancelled on the same signals by default, because the tunnel closes with the process; --no-cancel-on-interrupt skips the cancel but the tunnel still closes. Details and refunds: Cancelling a Run. With --output json, stderr carries an INTERRUPTED envelope with details.signal (not in the table below). A second signal exits immediately. If a reader closes a pipe early (... | head -n 1), the CLI exits 0.

Error codes

RATE_LIMITED with details.reason=tunnel_binding_limit is a standing capacity refusal and is not retried: run testsprite tunnel list, then stop an unused binding or reuse one with --tunnel-client.

Error output

With --output json, errors are an envelope on stderr; text mode prints message and nextAction.

Statuses

Test status is the outcome of the latest completed run: draft (no code yet), ready (has code, never run), queued, running, passed, failed (includes infra crash), blocked (rejected before a real verdict), unknown. cancelled is never emitted at test level; cancelling leaves the previous status. Run status: queued, running (non-terminal); passed, failed, blocked, cancelled (terminal). Step status: passed, failed, or null (not executed). Run source: cli (including test rerun), portal, mcp, schedule, github_action.

Retrying safely

Reuse --idempotency-key on write commands so retries are deduplicated server-side (why). Retry only exits 6 (CONFLICT), 10 and 11; for the others fix the cause first (check the ID, fix the input, top up credits, change plan). For tunnel-required, drop --no-wait or pass --local; tunnel-offline needs a live binding.

Where to Go Next

Command Reference

Every command and flag

CI/CD Integration

Gate pipelines on exit codes