Skip to main content

TheoApiError

All REST API errors are thrown as TheoApiError instances with structured details.

Error Properties

Error Types

TheoApiError is the base class — every error below is instanceof TheoApiError, so existing catch blocks keep working. Branch on the subclass (or err.kind) for precise handling:
  • TheoTimeoutError (kind: "timeout") — the SDK aborted after timeoutMs (unary / stream connect) or streamIdleTimeoutMs (stream idle). Carries the offending budget in .timeoutMs. Not auto-retried on POSTs.
  • TheoCancelledError (kind: "cancelled") — you aborted via TheoStream.cancel() or an AbortSignal passed to waitForJob().
  • TheoUsageError (extends Error, not TheoApiError) — thrown synchronously for misuse before any network call, e.g. passing mode: "research" | "video" to complete() / stream() (use the async job methods instead).

Stream Errors

The SSE error event carries the same envelope as the REST error body — reuse one code path for both.
This is a change from 0.1.x, where stream errors were { message } only. See the Streaming Completions reference for the full envelope schema.

First-Run Diagnostic

Instead of surfacing raw errors, theo.verify() returns a structured diagnosis with a remediation hint:
Call this as the first line of debugging on a 401. See 401 Troubleshooting for the common failure modes.

Automatic Retries

The SDK retries automatically on:
  • 429 — Rate limited (respects Retry-After header up to 60s)
  • 5xx — Server errors (exponential backoff: 1s, 2s, 4s, max 8s) Client errors (400, 401, 403, 404) are not retried. Timeouts are not retried on non-idempotent POSTs (complete, research, video) — re-issuing could double-run and double-bill the request; pair your own retry with an Idempotency-Key if you need one. See Timeouts & Retries for the full model, including the stream idle timeout. Configure:

Cancellation

TheoStream.cancel() aborts an in-flight stream without throwing. The underlying fetch is aborted via AbortController; subsequent events stop arriving and the iterator ends cleanly.