Errors

Read the error code, then take the matching recovery action.

At a glance

Envelope
error object
Busy
HTTP 409
Validation
HTTP 422
Transient
HTTP 503

Error envelope

Read error.code for recovery logic. Show error.message to a developer.

JSON
{
  "error": {
    "code": "tool_result_invalid",
    "message": "Tool result failed schema validation.",
    "request_id": "request_123",
    "details": [{"path": "content.title", "reason": "minLength"}]
  }
}

Error codes

Error codeMeaning
invalid_requestHTTP 400. Fix the request body or parameter.
invalid_cursorHTTP 400. Restart replay without the bad cursor.
authentication_requiredHTTP 401. Send a valid bearer key.
permission_deniedHTTP 403. Create a key with the required scope.
resource_not_foundHTTP 404. Check the id and workspace.
idempotency_conflictHTTP 409. Reuse a key only with the same payload.
event_already_resolvedHTTP 409. Do not execute the tool again.
event_expiredHTTP 409. Start a new run.
run_not_resumableHTTP 409. Read the run status. Start a new run if it is terminal.
SESSION_BUSYHTTP 409. Wait, cancel, or resume the active run.
RUN_NOT_CANCELLABLEHTTP 409. Treat the run as already terminal.
tool_input_invalidHTTP 422. Fix the tool input schema or prompt.
tool_result_invalidHTTP 422. Return an object matching the tool output schema.
RATE_LIMITEDHTTP 429. Wait for Retry-After before retrying. See Usage and limits.
runtime_resume_unavailableHTTP 503. Retry with the same idempotency key.
SANDBOX_PROVISION_FAILEDHTTP 503. Retry later or remove an unnecessary sandbox requirement.

SESSION_BUSY

HTTP 409
{
  "error": {
    "code": "SESSION_BUSY",
    "message": "Session 'session_123' has an active run 'run_123' in status 'waiting_for_input'.",
    "request_id": "request_123",
    "active_run_id": "run_123",
    "active_run_status": "waiting_for_input",
    "recovery": [
      "cancel the active run via POST /v1/sessions/session_123/runs/run_123/cancel",
      "or resume it via POST /v1/sessions/session_123/runs/run_123/resume"
    ]
  }
}

Read Sessions and runs for the recovery flow.

SANDBOX_PROVISION_FAILED

HTTP 503
{
  "error": {
    "code": "SANDBOX_PROVISION_FAILED",
    "message": "Sandbox provider quota is exhausted. Please retry later.",
    "request_id": "request_123"
  }
}

RATE_LIMITED

Tenant requests share three independent 60-second limits: 30 sessions, 60 runs, and 120 events.

HTTP 429 includes a Retry-After header with the wait in seconds.

HTTP 429, Retry-After: 12
{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Tenant rate limit reached.",
    "request_id": "request_123",
    "details": {"limit": 30, "window_seconds": 60, "retry_after": 12}
  }
}

details.limit is the configured request limit. details.window_seconds is the window length in seconds.

details.retry_after is the wait before retrying, matching the header.

See Usage and limits for affected operations. Request a higher limit through Support.

Recovery actions

SymptomAction
409 busyUse active_run_id. Resume or cancel that run.
503 sandboxBack off. Check quota. Disable sandboxing only when safe.
401Send Authorization: Bearer PANTHEON_API_KEY.
422 tool resultValidate the result against the registered output schema.
Stream dropsReconnect with the last durable SSE id. Handle stream.resync.

Pitfalls

  • Error code casing differs: Use the exact code returned by the API. The contract contains lowercase and uppercase codes.
  • A 422 leaves a run waiting: Correct the result and retry with the same idempotency key before the deadline.