Skip to content
sandbox-workers
Esc
navigateopen⌘Jpreview
On this page

Errors

The SandboxError hierarchy, the ErrorResponse shape, and the error code table.

Mode: both.

@sandbox-workers/core distinguishes two kinds of failure:

  • Guest errors — the executed code raised an exception, or hit a fuel/output/result limit. These never throw: runCode() still resolves, with the failure described in result.error (see Code interpreter).
  • Transport and request errors — a binding failure, a malformed response, or a non-200 response from the runtime Worker (an invalid path, a missing file, a bad request body, and so on). These are thrown as a SandboxError subclass.

This page covers the second kind.

The SandboxError hierarchy

Every thrown error is SandboxError or one of its subclasses, all exported by @sandbox-workers/core:

Class code Extra context fields
SandboxError any (base class; also thrown directly for a non-JSON or otherwise malformed error body, with code: "INTERNAL_ERROR")
FileNotFoundError FILE_NOT_FOUND path, operation
FileExistsError FILE_EXISTS path, operation
FileTooLargeError FILE_TOO_LARGE path, operation, maxSize, actualSize
PermissionDeniedError PERMISSION_DENIED path, operation
FileSystemError NO_SPACE, IS_DIRECTORY, NOT_DIRECTORY, or FILESYSTEM_ERROR path, operation
ContextNotFoundError CONTEXT_NOT_FOUND contextId
ValidationFailedError VALIDATION_FAILED validationErrors? (an array of { field, message })
CodeExecutionError CODE_EXECUTION_ERROR contextId?, ename?, evalue?

Binding validation errors

createCodeContext({ binding }) (and default-context resolution for runCode({ binding })) probes the named binding before creating anything, and throws ValidationFailedError with one of these messages when it fails:

Message Cause
Unknown binding 'X' No such key in your Worker’s env, or the name doesn’t match /^[A-Za-z_][A-Za-z0-9_]*$/
Binding 'X' is not a sandbox-workers runtime Worker The binding exists but has no fetch method, or GET /interpreter on it didn’t return { language, engine, contexts }
Code contexts are not supported by binding 'X' (language) The binding is a real runtime Worker, but it reports contexts: false (a stateless-only runtime Worker: Ruby, or one deployed with --stateless)
Pass a context or a binding runCode() was called with neither context nor binding

This probe runs only on createCodeContext and default-context creation, never on every execution.

Every instance also carries error.code, error.context, error.httpStatus, error.timestamp, and error.operation (getters backed by error.errorResponse, the raw ErrorResponse).

For filesystem failures specifically, error.context.errno carries the Node-style error code (ENOENT, EEXIST, EACCES, EISDIR, ENOTDIR, EFBIG, ENOSPC, ENOTEMPTY, …) alongside the mapped code in the table above.

import { FileNotFoundError } from "@sandbox-workers/core";

try {
  await sandbox.readFile("/workspace/missing.txt");
} catch (error) {
  if (error instanceof FileNotFoundError) {
    console.error(error.code, error.httpStatus, error.context.path);
    // "FILE_NOT_FOUND", 404, "/workspace/missing.txt"
  } else {
    throw error;
  }
}

ErrorResponse

The JSON shape every non-200 HTTP response carries, and the shape wrapped by every SandboxError:

interface ErrorResponse {
  code: string;
  message: string;
  context: Record<string, unknown>;
  httpStatus: number;
  timestamp: string;
  operation?: OperationType;
  suggestion?: string;     // typed for SDK parity; not currently emitted
  documentation?: string;  // typed for SDK parity; not currently emitted
}

operation, when present, is one of the dotted strings in the exported Operation object (Operation.FILE_READ = "file.read", Operation.FILE_WRITE = "file.write", Operation.FILE_DELETE = "file.delete", Operation.FILE_MOVE = "file.move", Operation.FILE_RENAME = "file.rename", Operation.FILE_STAT = "file.stat", Operation.DIRECTORY_CREATE = "directory.create", Operation.DIRECTORY_LIST = "directory.list", Operation.CODE_EXECUTE = "code.execute", Operation.CODE_CONTEXT_CREATE = "code.context.create", Operation.CODE_CONTEXT_DELETE = "code.context.delete"), typed as OperationType.

Error code table

code HTTP status Meaning
FILE_NOT_FOUND 404 Path does not exist
FILE_EXISTS 409 Path already exists (rename/move destination, non-force conflicts)
PERMISSION_DENIED 403 Path escapes /workspace, or the underlying EACCES
IS_DIRECTORY 400 Expected a file, found a directory; also deleteFile() on any directory without recursive: true
NOT_DIRECTORY 400 Expected a directory, found a file
FILE_TOO_LARGE 413 Exceeds the 1 MiB per-file or 16 MiB per-workspace limit
NO_SPACE 500 Workspace entry-count limit (4096) reached
FILESYSTEM_ERROR 500 ENOTEMPTY, any other filesystem error, or any failed mkdir (which always reports this code, regardless of the underlying errno)
CONTEXT_NOT_FOUND 404 Unknown contextId
VALIDATION_FAILED 400 Malformed request (also used with 413/415/405 for request-shape failures)
CODE_EXECUTION_ERROR 500 The engine failed before producing a result
INTERNAL_ERROR 500 Anything else, or a non-JSON response

See HTTP API for the full set of routes and status codes these errors come from.