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

# Handle errors and timeouts

> Cancel operations, configure timeouts, and handle command, RPC, and SDK errors.

Devbox operations distinguish command results from operation failures. Use operation options to cancel or time out work, and catch typed SDK or Connect errors when an operation cannot produce its normal result.

## `OperationOptions`

Devbox methods that perform remote work accept `signal` and `timeoutMs`, either directly or through a method-specific options type.

```typescript theme={null}
interface OperationOptions {
  signal?: AbortSignal;
  timeoutMs?: number;
}
```

<ResponseField name="signal" type="AbortSignal">
  Cancels the operation when the signal is aborted. An already-aborted signal prevents the operation from starting.
</ResponseField>

<ResponseField name="timeoutMs" type="number">
  The operation's timeout budget in milliseconds.
</ResponseField>

For connection-backed operations with multiple phases, such as activating a stopped Devbox and then connecting to it, `timeoutMs` must be finite and non-negative and establishes one deadline shared by all phases. It is not reset after activation or connection. A timeout rejects with `DevboxTimeoutError`. Resource RPCs pass the timeout to Connect and can instead reject with a `ConnectError` whose code is `DeadlineExceeded`.

### Example

Set a 30-second budget for activation, connection, and command execution:

```typescript {2-3} theme={null}
const devbox = await client.devboxes.get("sdk-example");
const result = await devbox.exec(["npm", "test"], {
  timeoutMs: 30_000,
});
```

Abort an operation from application code:

```typescript {1-2,5} theme={null}
const controller = new AbortController();
process.once("SIGINT", () => controller.abort());

const devbox = await client.devboxes.get("sdk-example");
await devbox.exec(["npm", "test"], { signal: controller.signal });
```

When a connection-backed operation is aborted, it rejects with `signal.reason` if it is an `Error`. Otherwise it rejects with an `Error` whose `name` is `"AbortError"`. Cancellation is not represented by a `DevboxError` subclass. See [Use interactive terminals](/docs/reference/typescript-sdk/terminals) for terminal-specific signal behavior.

## Command results and rejected operations

`exec()` and `shell()` resolve with an `ExecResult` when the remote command runs, including when it exits non-zero. Check `exitCode`, `signal`, and `error` instead of relying on `catch` for command failure.

```typescript {2-4} theme={null}
const devbox = await client.devboxes.get("sdk-example");
const result = await devbox.shell("npm test");
if (result.exitCode !== 0) {
  throw new Error(result.error ?? result.stderr);
}
```

The promise rejects when the operation itself fails, including invalid input, abort, timeout, RPC or gateway failure, or an incomplete service response. `fs.copy()` and recursive `fs.remove()` run commands internally and reject with an ordinary `Error` when those helper commands fail.

See [Run commands](/docs/reference/typescript-sdk/commands) for the complete `ExecResult` fields.

## `ConnectError`

Namespace API failures surface as `ConnectError` from `@connectrpc/connect`. Inspect its Connect `code` for programmatic handling. Agent command `DeadlineExceeded` errors are converted to `DevboxTimeoutError`; other RPC deadline failures can remain `ConnectError` instances.

```typescript {6-7} theme={null}
import { Code, ConnectError } from "@connectrpc/connect";

try {
  await client.devboxes.get("devbox-id");
} catch (error) {
  if (error instanceof ConnectError && error.code === Code.NotFound) {
    console.error("Devbox not found");
  } else {
    throw error;
  }
}
```

## `DevboxError`

Base class for errors created by the Devbox SDK. Catch it to handle any SDK-level Devbox failure while allowing abort errors and `ConnectError` to follow separate paths.

```typescript theme={null}
class DevboxError extends Error
```

## `DevboxTimeoutError`

The operation exhausted an SDK-managed `timeoutMs` budget. This can happen during a connection-backed operation's activation, connection, handshake, or remote work, including command execution.

```typescript theme={null}
class DevboxTimeoutError extends DevboxError {
  constructor(message: string, readonly timeoutMs?: number);
}
```

<ResponseField name="timeoutMs" type="number">
  The configured timeout in milliseconds when that value is available at the point where the error is created.
</ResponseField>

## `DevboxGatewayError`

The Devbox gateway or display endpoint rejected a connection with an HTTP error. The status code is available for logging or conditional handling. Authentication failures commonly use status `401` or `403` and are not retried by the connection manager.

```typescript theme={null}
class DevboxGatewayError extends DevboxError {
  constructor(readonly statusCode: number);
}
```

<ResponseField name="statusCode" type="number" required>
  The HTTP response status returned by the gateway.
</ResponseField>

## `DevboxDisplayUnavailableError`

The Devbox does not expose the VNC display service. This appears when using `devbox.display` with a Devbox that has no graphical display.

```typescript theme={null}
class DevboxDisplayUnavailableError extends DevboxError
```

## `IncompleteResponseError`

The service response omitted a field required to complete an operation. It can appear when a create, get, update, or lifecycle response lacks its Devbox value, or when a command stream ends without a final result.

```typescript theme={null}
class IncompleteResponseError extends DevboxError {
  constructor(context: string);
}
```

## `ImageOptimizationError`

Image optimization reported failure, or its event stream ended before reporting completion.

```typescript theme={null}
class ImageOptimizationError extends DevboxError
```

## Catch Devbox failures

Import Devbox error classes from `@namespacelabs/sdk/devbox`. Check specific classes before their `DevboxError` base class.

```typescript {10,12-17} theme={null}
import {
  DevboxError,
  DevboxGatewayError,
  DevboxTimeoutError,
} from "@namespacelabs/sdk/devbox";

const devbox = await client.devboxes.get("sdk-example");

try {
  await devbox.exec(["npm", "test"], { timeoutMs: 60_000 });
} catch (error) {
  if (error instanceof DevboxTimeoutError) {
    console.error("The Devbox operation did not finish in time.");
  } else if (error instanceof DevboxGatewayError) {
    console.error(`Gateway returned HTTP ${error.statusCode}.`);
  } else if (error instanceof DevboxError) {
    console.error(error.message);
  } else {
    throw error;
  }
}
```

Handle aborts separately when cancellation is expected:

```typescript {6-8} theme={null}
const devbox = await client.devboxes.get("sdk-example");

try {
  await devbox.exec(["sleep", "60"], { signal });
} catch (error) {
  if (error instanceof Error && error.name === "AbortError") {
    return;
  }
  throw error;
}
```

## Related documentation

<Columns cols={3}>
  <Card title="Run commands" icon="terminal" href="/docs/reference/typescript-sdk/commands">
    Interpret command exit codes and output.
  </Card>

  <Card title="Use interactive terminals" icon="square-terminal" href="/docs/reference/typescript-sdk/terminals">
    Open, close, and wait for terminal sessions.
  </Card>

  <Card title="Authenticate with Namespace" icon="key" href="/docs/reference/typescript-sdk/authentication">
    Configure credentials and handle authentication failures.
  </Card>
</Columns>
