Skip to content

Troubleshooting

Last updated View as MarkdownAgent setup

Use this symptom-to-fix map. For deeper recovery, refer to Errors and recovery. For lifecycle behavior, refer to Sandbox lifecycle.

Deploy and image

Symptom What to check
RuntimeControlProtocolError, control/protocol failures after deploy Worker package and container image are on different lines. Use the same @next / cloudflare/sandbox:next (or the same exact prerelease) pair.
Container never becomes ready, or you see repeated ContainerUnavailableError Cold start or capacity. Back off using retryAfterMs when set, then retry the work. Refer to Errors and recovery.
Works in wrangler dev, fails in production only Production-only limits and cold start. Still keep package/image matched.

Processes

Symptom What to check
await exec “finished” but the command did not exec resolves on launch. Use output(), waitForExit(), or exitCode.
No stdout as a string output() defaults to bytes. Pass { encoding: "utf8" }.
getProcess is null / list is [] No container running, or ID unknown in the current container. Discovery does not wake a sandbox. Relaunch from stored job state if needed.
StaleProcessHandleError Handle was from a previous container. Start a new exec from checkpointed work.
Wait timed out / aborted but process still runs Local wait only. Call kill() if you intend to stop it.
Port never becomes ready Default waitForPort mode is TCP. Use mode: "http" for HTTP checks. Process may have exited — check status/logs.
Need interactive stdin Not on the process handle. Use a terminal or non-interactive argv/cwd/env.

Terminals

Symptom What to check
Browser still uses sessionId Preview xterm helper expects terminalId.
getTerminal is null Same lifetime rules as processes. Create again if the container was replaced.
Reconnect has no history Pass the last cursor into connect / output options.

Environment and secrets

Symptom What to check
Env from an earlier exec “disappeared” No session shell. Use setEnvVars and/or per-launch env. Environment variables.
API keys leaked into the container Do not put live secrets in sandbox env. Use outbound traffic handlers on the Worker.

Interpreter

Symptom What to check
sandbox.createCodeContext is not a function Attach withInterpreter and call sandbox.interpreter.*.
Python not available Use the -python image variant on the same @next line.

Bridge HTTP

Symptom What to check
Bridge /exec, sessions, or /pty behavior differs from @next Worker SDK docs The self-deployed bridge is not part of the 1.0 preview. Use the stable bridge with matching stable package and container image.

Agents and long-running jobs

For agents and long-running tools on @next:

  1. Launch with exec(argv) (often ['/bin/bash', '-lc', script]).
  2. Wait with waitForLog, waitForPort, or logs — not only await exec.
  3. Persist job state (command, cwd, env, checkpoint), not only process.id.
  4. On a later request: getProcess(id) while the same container may still hold it; otherwise exec again.
  5. Use a terminal only when you need a human PTY, not as a session substitute.

Refer to Process execution, Migrate, and examples in the sandbox-sdk repo (claude-code, codex, opencode, and others).

Was this helpful?