Developer Manual

Errors

Errors use standard HTTP status codes and a JSON error field. The SDK maps each status to its own subclass of EClipsError, and each one carries statusCode and code.

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, so 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.