Every Roadie endpoint returns failures in one uniform JSON envelope:
  • type — one of ten stable categories.
  • code — a stable, machine-readable identifier you can branch on.
  • param — the offending field, when the error is about one.
  • request_id — ties the failure to your logs (also returned on the X-Request-Id header).
Messages never contain provider raw bodies, key material, or internal hostnames. For the complete list of types and codes, see the error reference.

Typed errors in the SDK

The SDK maps the envelope onto one RoadieError subclass per type, plus client-side classes for network, timeout, abort, and misconfiguration failures. Branch with instanceof, or use isRoadieError:
Server-mapped classes: InvalidRequestError, AuthenticationError, PermissionError, NotFoundError, RateLimitError, QuotaError, BudgetError, ProviderError, IdempotencyError, InternalError. Client-side classes: APIConnectionError, APIConnectionTimeoutError, APIUserAbortError, RoadieConfigurationError.

Automatic retries

The SDK retries only safe-to-repeat, pre-first-byte failures — network errors and 408 / 429 / 5xx responses — with exponential backoff and equal jitter, honoring Retry-After (both capped at 8 s per attempt). The default is maxRetries: 2. A typed error reaches your catch only after retries are exhausted.
The retry decision is made on the HTTP status, before the error is typed. So the SDK never retries validation (400), auth (401), permission (403), not-found (404), idempotency (409), or budget (402) failures — retrying those cannot help — but it does retry every 429, which includes both rate_limit_error and quota_error (they share the 429 status). A quota retry can’t succeed until the window resets, so a QuotaError still surfaces to your catch once the handful of retries are exhausted. Rate-limit responses also carry X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset; the SDK surfaces these as result.rateLimit and err.retryAfter. See Rate limits, quotas & budgets.

Retries are safe because of idempotency

Because a retried request could otherwise execute twice, the SDK attaches a stable Idempotency-Key to non-streaming create calls and reuses it across every attempt, so the gateway de-duplicates a retried chat request rather than running it twice. That mechanism — exactly-once semantics and the 409 conflict on a key reused with a different body — has its own page: Idempotency & retries.

Timeouts

A per-request timeoutMs composes with any AbortSignal you pass. A fired deadline throws APIConnectionTimeoutError; a caller abort throws APIUserAbortError.

Mid-stream errors

A streaming request that fails after it has started emits a terminal error frame (see Streaming) rather than an HTTP error status, because the 200 response has already begun. The SDK surfaces it as an error event in the iterable.