# Errors
URL: /docs/core/api-reference/errors

CommandError, SandboxError, ExecConnectionError, WorkflowError, and SandboxClientError — the full alineo error hierarchy.



```ts
import {
  CommandError,
  SandboxError,
  ExecConnectionError,
  WorkflowError,
  SandboxClientError,
} from "@alineo-labs/sandbox";
```

## Error hierarchy [#error-hierarchy]

```
Error
├── WorkflowError            — base class for Sandbox-level errors
│   ├── SandboxError        — sandbox lifecycle failure: create/boot/Running, paused, unsupported fork(), or snapshot
│   ├── ExecConnectionError — execd not ready after retry window
│   └── CommandError        — non-zero exit code in strict mode
└── SandboxClientError                — client-level errors from Sandbox itself (not a WorkflowError)
```

`SandboxError`, `ExecConnectionError`, and `CommandError` all extend `WorkflowError`, which extends `Error` — catch all three with `e instanceof WorkflowError`. `SandboxClientError` is a separate, sibling class thrown by `Sandbox` client methods (`sandbox()`, `resume()`, `sandboxes.*`, `environment()`) rather than by `Sandbox` methods — see [SandboxClientError](#alineoerror) below.

## WorkflowError [#workflowerror]

Base class. Has `message` and `name` properties. `name` is always `"WorkflowError"`.

```ts
import { WorkflowError } from "@alineo-labs/sandbox";

try {
  await sb.exec("cmd");
} catch (e) {
  if (e instanceof WorkflowError) {
    console.error("alineo error:", e.message);
  } else {
    throw e;
  }
}
```

## CommandError [#commanderror]

Thrown when `sb.exec()` exits with a non-zero code and `strict: true` (the default).

```ts
import { CommandError } from "@alineo-labs/sandbox";

try {
  await sb.exec("exit 42");
} catch (e) {
  if (e instanceof CommandError) {
    console.error(`exit ${e.exitCode}`); // 42
    console.error(`command: ${e.command}`); // "exit 42"
    console.error(`sandbox: ${e.sandboxId}`);
  }
}
```

### Properties [#properties]

| Property    | Type     | Description                           |
| ----------- | -------- | ------------------------------------- |
| `exitCode`  | `number` | The process exit code                 |
| `command`   | `string` | The command string that was run       |
| `sandboxId` | `string` | The sandbox ID where it ran           |
| `message`   | `string` | `"Command exited with code N: <cmd>"` |
| `name`      | `string` | `"CommandError"`                      |

### Avoiding CommandError [#avoiding-commanderror]

Pass `{ strict: false }` to get the exit code in the result:

```ts
const { exitCode } = await sb.exec("test -f /etc/hosts", { strict: false });
```

## SandboxError [#sandboxerror]

Thrown by methods on `SandboxHandle` itself: `resume()` if the container never reaches `Running` (or enters `Failed`/`Terminated`), an exec call while the sandbox is paused, `fork()` when the deps don't support it, or a failed snapshot wait.

A failure during `client.sandbox()`'s own initial creation throws `SandboxClientError`, not `SandboxError` — see below.

```ts
import { SandboxError } from "@alineo-labs/sandbox";

try {
  await sb.resume(); // sandbox previously pause()d, now stuck
} catch (e) {
  if (e instanceof SandboxError) {
    console.error(e.message); // e.g. "Sandbox entered Failed: ..." or "sandbox is paused — call resume() first"
    console.error(e.sandboxId ?? ""); // sandbox ID if assigned before failure
  }
}
```

### Properties [#properties-1]

| Property    | Type                  | Description                                         |
| ----------- | --------------------- | --------------------------------------------------- |
| `sandboxId` | `string \| undefined` | Container ID if one was assigned before the failure |
| `message`   | `string`              | Describes what failed                               |
| `name`      | `string`              | `"SandboxError"`                                    |

## ExecConnectionError [#execconnectionerror]

Thrown when the execd daemon inside the container never becomes ready within the retry window (\~15 seconds). The container is `Running` from OpenSandbox's perspective, but the exec daemon isn't accepting connections.

```ts
import { ExecConnectionError } from "@alineo-labs/sandbox";

try {
  await sb.exec("echo test");
} catch (e) {
  if (e instanceof ExecConnectionError) {
    console.error(e.message); // "execd not ready for sandbox <id>"
    console.error(e.sandboxId); // the sandbox ID
  }
}
```

### Properties [#properties-2]

| Property    | Type     | Description                          |
| ----------- | -------- | ------------------------------------ |
| `sandboxId` | `string` | The sandbox ID                       |
| `message`   | `string` | `"execd not ready for sandbox <id>"` |
| `name`      | `string` | `"ExecConnectionError"`              |

This usually means the container image doesn't include execd, or the container started but the execd process crashed.

## SandboxClientError [#sandboxclienterror]

Thrown by the `Sandbox` client for API-level errors (404 not found, timeouts waiting for Running state):

```ts
import { SandboxClientError } from "@alineo-labs/sandbox";

try {
  await client.resume("nonexistent-id");
} catch (e) {
  if (e instanceof SandboxClientError) {
    console.error(e.message); // "Session nonexistent-id not found"
    console.error(e.status); // 404
  }
}
```

`SandboxClientError` is not a `WorkflowError` — it's a separate class for client-level errors.
