--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:
--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