Errors
Every failure the SDK raises is a subclass of CreateosSandboxError. Catch the
base class to handle all SDK failures uniformly, or narrow with instanceof to a
specific subclass when you need HTTP-status or transport-level detail.
Errors surface only after the built-in retry policy is exhausted — see
Reliability for retry semantics.
At a glance
- Package:
@nodeops-createos/sandbox(npm) - Import:
import { createClient } from "@nodeops-createos/sandbox" - Base URL:
https://api.sb.createos.sh— override withCREATEOS_SANDBOX_BASE_URL - Auth: API key via the
apiKeyoption orCREATEOS_SANDBOX_API_KEY
Hierarchy
CreateosSandboxError
├─ CreateosSandboxApiError non-2xx HTTP response
│ ├─ CreateosSandboxAuthError 401
│ ├─ CreateosSandboxPermissionError 403
│ ├─ CreateosSandboxNotFoundError 404
│ ├─ CreateosSandboxPaymentRequiredError 402
│ ├─ CreateosSandboxValidationError 400 / 409 / 422
│ ├─ CreateosSandboxRateLimitError 429
│ └─ CreateosSandboxServerError 5xx
├─ CreateosSandboxConnectionError network failure (no response received)
└─ CreateosSandboxTimeoutError request or waitUntil* deadline exceeded
HTTP status → error class
| HTTP status | Error class |
|---|---|
| 401 | CreateosSandboxAuthError |
| 402 | CreateosSandboxPaymentRequiredError |
| 403 | CreateosSandboxPermissionError |
| 404 | CreateosSandboxNotFoundError |
| 400, 409, 422 | CreateosSandboxValidationError |
| 429 | CreateosSandboxRateLimitError |
| 5xx | CreateosSandboxServerError |
| other non-2xx | CreateosSandboxApiError (base) |
| network failure | CreateosSandboxConnectionError |
| deadline exceeded | CreateosSandboxTimeoutError |
Common fields
CreateosSandboxError (base)
All SDK errors extend this class. It carries only:
| Field | Type | Description |
|---|---|---|
message | string | Human-readable description of the failure. |
name | string | Class name of the concrete error (e.g. "CreateosSandboxNotFoundError"). Set via new.target.name; matches the constructor even through inheritance. |
cause | unknown | undefined | Underlying cause, forwarded from the options.cause constructor argument (standard Error options). Present on CreateosSandboxConnectionError and CreateosSandboxTimeoutError when an underlying fetch or abort error is available. |
CreateosSandboxApiError (all HTTP errors)
Extends CreateosSandboxError. Present on every non-2xx response.
| Field | Type | Description |
|---|---|---|
statusCode | number | HTTP response status code. |
response | Response | Raw fetch Response object. Headers, body, and URL are accessible here. |
envelope | FailEnvelope | ErrorEnvelope | undefined | Parsed JSend fail or error body, when the server returned a parseable envelope. |
requestId | string | undefined | Value of the x-request-id or x-fc-request-id response header, when present. Include this in bug reports. |
resourceId | string | undefined | Resource id parsed from the request path (e.g. the sandbox, template, network, or disk id), when the path matches /v1/{sandboxes|templates|networks|disks}/{id}. |
code | string | undefined | Stable machine-readable code from envelope.data.code, when the server included one. |
endpoint | string | undefined | URL pathname of the request (no host, no query string). |
method | string | undefined | HTTP method used (GET, POST, etc.). |
ErrorRequestContext type
TypeScript1import type { ErrorRequestContext } from "@nodeops-createos/sandbox";
The interface the transport passes internally when constructing API errors.
You do not construct this directly; it appears as the source of
endpoint and method fields on CreateosSandboxApiError.
TypeScript1interface ErrorRequestContext {2 endpoint?: string; // URL pathname, no host or query3 method?: string; // HTTP method4}
Per-class reference
CreateosSandboxAuthError
Status: 401
When thrown: The API key is missing, revoked, or rejected by the control
plane. Check that CREATEOS_SANDBOX_API_KEY is set, or that you passed
apiKey to the client constructor (see client reference).
No subclass-specific fields beyond those on CreateosSandboxApiError.
CreateosSandboxPermissionError
Status: 403
When thrown: The API key authenticated successfully but is not authorized
to access the requested resource — quota, ACL mismatch, or cross-tenant
access attempt.
No subclass-specific fields.
CreateosSandboxNotFoundError
Status: 404
When thrown: The sandbox, template, network, or disk id does not resolve
to an existing resource in this tenant. Check resourceId to confirm which
id was unresolvable.
No subclass-specific fields.
CreateosSandboxPaymentRequiredError
Status: 402
When thrown: The account has insufficient credit. The control plane gates
cost-incurring operations — sandbox create, resume, fork, bandwidth
recharge, and disk/network/template creation — on a positive balance. Top up
your account; retrying without doing so returns the same error.
No subclass-specific fields.
CreateosSandboxValidationError
Statuses: 400, 409, 422
When thrown: The request shape, body field values, or current resource
state makes the operation invalid. Common causes: unknown shape name, invalid
state transition, field-level validation failure (400/422), conflicting
concurrent operation (409). Inspect message and code for the server's
explanation.
No subclass-specific fields.
CreateosSandboxRateLimitError
Status: 429
When thrown: The caller exceeded the request rate limit. The SDK retries
429 responses automatically with exponential backoff before surfacing this
error — see Reliability.
Additional field:
| Field | Type | Description |
|---|---|---|
retryAfterSeconds | number | undefined | Seconds to wait before retrying, parsed from the Retry-After response header. Supports both delta-seconds and HTTP-date formats. undefined when the header is absent or unparseable. |
CreateosSandboxServerError
Statuses: 500, 502, 503, 504, and any other 5xx
When thrown: The control plane accepted the request but failed to fulfil
it — host capacity exhausted, internal error, or upstream component
unavailable. The SDK retries idempotent methods on 500/502/503/504 before
surfacing this error.
No subclass-specific fields.
CreateosSandboxConnectionError
When thrown: The request never reached the server — DNS resolution
failure, connection refused, or socket reset. There is no HTTP response.
cause holds the underlying network error when available.
Inherits directly from CreateosSandboxError; does not carry
statusCode, response, or the other CreateosSandboxApiError fields.
CreateosSandboxTimeoutError
When thrown: A per-request timeout or a waitUntilRunning /
waitUntilStopped poll deadline was exceeded. cause holds the underlying
AbortError when available.
Inherits directly from CreateosSandboxError; does not carry
statusCode, response, or the other CreateosSandboxApiError fields.
Handling errors
Import only what you need:
TypeScript1import {2 CreateosSandboxError,3 CreateosSandboxAuthError,4 CreateosSandboxNotFoundError,5 CreateosSandboxPaymentRequiredError,6 CreateosSandboxRateLimitError,7 CreateosSandboxValidationError,8 CreateosSandboxConnectionError,9 CreateosSandboxTimeoutError,10} from "@nodeops-createos/sandbox";
Basic narrowing pattern:
TypeScript1const client = createClient({ apiKey: process.env.CREATEOS_SANDBOX_API_KEY });2let sandbox;34try {5 sandbox = await client.createSandbox({ rootfs: "base-ubuntu-22" });6 await sandbox.waitUntilRunning();78 // … do work …9} catch (err) {10 if (err instanceof CreateosSandboxAuthError) {11 // API key missing or invalid — do not retry.12 console.error("Authentication failed. Check CREATEOS_SANDBOX_API_KEY.");13 throw err;14 }1516 if (err instanceof CreateosSandboxPaymentRequiredError) {17 // Insufficient credit — do not retry.18 console.error("Account out of credit. Top up to continue.");19 throw err;20 }2122 if (err instanceof CreateosSandboxNotFoundError) {23 // Resource does not exist — resourceId tells you which one.24 console.error(`Resource not found: ${err.resourceId}`);25 throw err;26 }2728 if (err instanceof CreateosSandboxRateLimitError) {29 // SDK has already retried. If you are managing your own retry loop,30 // respect retryAfterSeconds.31 const delay = err.retryAfterSeconds ?? 60;32 console.warn(`Rate limited. Retry after ${delay}s.`);33 throw err;34 }3536 if (err instanceof CreateosSandboxValidationError) {37 // Bad request shape or state conflict. Check err.message and err.code.38 console.error(`Validation error [${err.code ?? err.statusCode}]: ${err.message}`);39 throw err;40 }4142 if (err instanceof CreateosSandboxTimeoutError) {43 console.error("Timed out:", err.message, err.cause);44 throw err;45 }4647 if (err instanceof CreateosSandboxConnectionError) {48 console.error("Network failure:", err.message, err.cause);49 throw err;50 }5152 if (err instanceof CreateosSandboxError) {53 // Catch-all for any other SDK error (e.g. unexpected 5xx after retries).54 console.error(`SDK error (${(err as CreateosSandboxApiError).statusCode}): ${err.message}`);55 throw err;56 }5758 // Non-SDK error — rethrow as-is.59 throw err;60} finally {61 if (sandbox) {62 await sandbox.destroy();63 }64}
Retry behaviour. Idempotent methods (GET, HEAD, PUT, DELETE) are
retried automatically on network errors and on 408, 500, 502, 503,
504. Non-idempotent methods (POST, PATCH) are retried only on 429 and
503 — statuses where the server provably did not process the request.
Streaming requests are never retried. Errors surface only after all
retry attempts are exhausted. Full details in
Reliability.
Request ids. When filing a bug or opening a support ticket, include
err.requestId — the control plane uses it to correlate server-side logs.
See also: Client reference · Sandbox reference · Error handling how-to