> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usestatemachines.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SDK error reference

> Public error classes, retry boundaries, cancellation, and management error codes.

The SDK separates failed management calls from failed waits. Native app responses have their own error formats and are returned as `Response` objects by `credentials.fetch()`.

## Public error classes

| Class | Meaning and available data |
| - | - |
| `StateMachinesError` | A management call failed, a response was invalid, or local validation refused input. Fields are `message`, `status`, `code`, `requestId`, `fields`, and `retryAfterMs`. |
| `EnvironmentFailedError` | A wait cannot reach its target because the environment failed, including deletion with reason `failed`. Extends `StateMachinesError` and carries `environment`. Read the startup failure through `environment.failure`. |
| `SnapshotFailedError` | A wait encountered a failed snapshot. Extends `StateMachinesError` and carries `snapshot`. Read `snapshot.failure`. |
| `UnexpectedStatusError` | A known status cannot reach the target without another action. Carries `resource` and its actual `status`. Extends `Error`, not `StateMachinesError`. |
| `WaitTimeoutError` | The whole wait deadline expired. Carries `timeoutMs` and `resource`, the last successful read or null if there was none. Extends `Error`, not `StateMachinesError`. |

Check specific subclasses before `StateMachinesError`. A failure code such as `invalid_settings` belongs to `environment.failure.code`. It is not the `code` property of `EnvironmentFailedError`.

For `StateMachinesError`, `status` is the HTTP status or null. A null value can mean no response arrived, local validation failed, or response parsing failed. `code` can also be null. Neither field alone establishes whether the server accepted a mutation.

`fields` maps dotted input paths to arrays of messages. `requestId` identifies a management request when available. `retryAfterMs` converts the server's `Retry-After` value into milliseconds. These properties can be null.

## Polling outcomes

`wait(id, { status })` checks the target before classifying failure. Waiting explicitly for `failed` resolves when that status is read. Waiting for `running` from `paused` throws `UnexpectedStatusError` because resumption needs a separate call.

Environment waits understand `starting`, `running`, `paused`, `failed`, and `deleted`. Snapshot waits understand `saving`, `ready`, `failed`, and `deleted`. An unfamiliar response status is polled until the target or deadline, allowing for server states introduced after this SDK.

Polling retries connection failures, read timeouts, and HTTP 502, 503, and 504 with backoff. A `Retry-After` value can delay the next poll. Other HTTP failures, such as authentication or validation failures, stop the wait. Each poll read times out after 30 seconds or at the wait deadline, whichever comes first. The polling loop owns its retries rather than nesting the generated client's retry loop.

## Timeout and cancellation

`attemptTimeoutMs` is a constructor option for each management HTTP attempt. `timeoutMs` is an option for the wait as a whole. In create and resume helpers, the wait begins after the initial operation succeeds. `timeoutMs` defaults to 600000. A negative value throws `RangeError`. Zero expires without reading the resource.

Aborting an explicit wait rejects with the caller's `signal.reason`. Aborting the initial management request rejects with `StateMachinesError`, whose cause records the abort. Application code can check its own signal's `aborted` state to distinguish cancellation from another failure.

Cancellation and timeout stop observation. They do not delete an environment, stop snapshot saving, or reverse a resume. [Recovery](/sdk-api/recovery) describes how to retain IDs and resume observation.

## Management error codes

The SDK's `ErrorCode` type and `openapi.json` contain the full error vocabulary. Codes relevant to environment work include:

| Code | Status | Meaning for the caller |
| - | - | - |
| `invalid_request` | 400 | Input failed validation. Inspect `fields` and correct the input before resubmitting. |
| `unauthenticated` | 401 | The management bearer credential is absent, invalid, expired, or revoked. |
| `forbidden` | 403 | The caller lacks the required permission or organization context. |
| `not_found` | 404 | The resource is absent or outside the caller's permitted scope. |
| `invalid_status` | 409 | The resource cannot perform the operation in its current status. |
| `snapshot_in_progress` | 409 | This environment already has a snapshot saving. |
| `idempotency_key_reused` | 409 | The same create key was reused with different input. |
| `workspace_archived` | 409 | The workspace does not accept this change while archived. |
| `body_too_large` | 413 | The management request body exceeds the accepted size. |
| `version_unavailable` | 422 | The app has no default version. |
| `environment_limit_reached` | 429 | The caller has reached the applicable concurrent environment allowance. |
| `internal_error` | 500 | The service failed to complete the request. Preserve the request ID for diagnosis. |
| `unavailable` | 503 | A management dependency or the service is temporarily unavailable. |

A code is not a general instruction to retry. The SDK retries a management call after a connection failure, an attempt timeout, or HTTP 502, 503 or 504. It backs off from 1 second to 5 seconds and stops retrying after 10 minutes. It does not retry any 4xx status, 429 or 500. It never retries native app requests.

Error messages avoid embedding raw management response bodies. Application logs still need to exclude credential objects, custom fetch inputs, and bearer headers.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.