Developer Manual

Errors

Errors use standard HTTP status codes and a JSON error field. The SDK maps each status to a catchable subclass of EClipsError, every one carrying statusCode and code so you can branch precisely.

Error shape

Failures return a JSON body with an error message; some add fields such as required and provided (scope checks) or field (validation).

json
{ "error": "task is required" }

// Some errors carry extra fields. A 403 from a scope check:
{ "error": "Insufficient scope", "required": "agents:run", "provided": ["agents:read"] }

Status codes → SDK classes

Every EClipsError exposes statusCode (the HTTP status) and code (a machine-readable string).

400Validation error — the request body or parameters failed validation (e.g. missing task, unknown agent_type, >500 batch rows). SDK: ValidationError (err.field names the offending field when reported).
401Authentication error — missing, invalid, expired, or revoked API key. SDK: AuthenticationError.
403Permission — the key lacks the required scope, or the org's plan does not include API access. SDK: PermissionError.
404Not found — the run, triage item, webhook, or batch does not exist for your org. SDK: NotFoundError.
408Timeout — the SDK's waitForRun gave up before the run finished (the run itself may still complete). SDK: TimeoutError. This is raised client-side, not returned by the API.
422Unprocessable — semantic validation failure. The SDK has no dedicated subclass; it surfaces as a base EClipsError with statusCode 422.
429Rate limited or out of credits — too many requests, or the org has exhausted its plan/top-up credits. Respect Retry-After. SDK: RateLimitError (err.retryAfter in seconds).
Note:The SDK maps 400 → ValidationError, 401 → AuthenticationError, 403 → PermissionError, 404 → NotFoundError, and 429 → RateLimitError. TimeoutError (status 408) is thrown locally by waitForRun. Any other status — including 422 and 5xx — surfaces as the base EClipsError.

Handling errors

Branch on the error class to handle each case. Order matters: check subclasses before the base EClipsError.

typescript
import {
  EClipsError,
  AuthenticationError,
  PermissionError,
  RateLimitError,
  ValidationError,
  NotFoundError,
  TimeoutError,
} from "@eclips/sdk";

try {
  const result = await client.runAndWait("ap_specialist", task);
} catch (err) {
  if (err instanceof AuthenticationError) {
    // 401 — missing, invalid, expired, or revoked API key
  } else if (err instanceof PermissionError) {
    // 403 — the key lacks the required scope, or the plan lacks API access
  } else if (err instanceof RateLimitError) {
    await sleep((err.retryAfter ?? 60) * 1000); // seconds from Retry-After
  } else if (err instanceof ValidationError) {
    // 400 — err.field names the offending field, if reported
  } else if (err instanceof NotFoundError) {
    // 404 — run, triage item, webhook, or batch not found for your org
  } else if (err instanceof TimeoutError) {
    // 408 — waitForRun gave up; the run may still complete — poll getRun(...) later
  } else if (err instanceof EClipsError) {
    // Any other status (e.g. 422, 500) — inspect err.statusCode and err.code
  }
}

Error class reference

EClipsErrorBase class. Carries statusCode and code. Catches any failure the SDK does not map to a more specific class.
AuthenticationError401 / authentication_error — bad or missing API key.
PermissionError403 / permission_error — missing scope or no plan API access.
RateLimitError429 / rate_limit_error — adds retryAfter (number | null).
ValidationError400 / validation_error — adds field (string | null).
NotFoundError404 / not_found — resource not found for your org.
TimeoutError408 / timeout — raised by waitForRun; the run may still complete.
Tip:An out-of-credit condition surfaces as a credit-related 429; check the error message and your /v1/usage summary to distinguish a frequency rate limit from an exhausted balance. See Rate limits & plans.