# Diagnose a sandbox integration Start with the failing step: connection, creation, readiness, execution, pause, wake or cleanup. Every error carries a `code`, a `hint` and a `requestId`: follow the hint first, and keep the request id, the sandbox id, the time and the SDK version for a report. Never include API keys, connection secrets or private file contents in a report. Confirm you are using the correct account and API origin. If it looks like Runtime's fault, report it with `npx withruntime feedback "..." --request-id `; if you are stuck, ask `npx withruntime support "..."`. See [feedback and support](./feedback-and-support). ## Browser login does not finish Open the exact link the CLI printed, verify the matching code and agent name, then approve **Connect agent** as the account owner. If the command was stopped while it waited, run it again: it shows the same link and code, and picks up the approval. Approval and delivery are separate: the browser waits for the CLI to receive and verify the credential before showing success. Requests expire after 15 minutes. Start a new `npx withruntime login` after expiry. On a remote terminal, use `--no-browser` and open its link on your own device. If the CLI cannot reach Runtime, check its outbound HTTPS access; do not paste credentials into the browser or into your agent's prompt. Run `npx withruntime whoami` to check a saved connection. If it is refused, run login again. `RUNTIME_API_KEY` overrides the saved connection: an invalid environment key can fail even when browser login previously worked. Remove an unwanted override without printing its value. ## Creation is refused | Code | What it means | What to do | | --------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------- | | `trial_busy` | Three trial sandboxes are already running or paused; `details` names them | Stop one, or pass `funding: "paid"` | | `trial_exhausted` | The 20 hours are used, or `timeoutSeconds` is more than what is left | Shorten `timeoutSeconds`, or use paid credit | | `invalid_trial` | A trial sandbox is at most 2 vCPU, 4 GiB of memory and 10 GiB of disk | Omit the size fields for the default | | `invalid_request` | `details.issues` names every wrong field | Fix the named fields; unknown fields are refused | | `invalid_region` | `details.available` lists your regions | Use a region listed for your account, or omit it | | `no_capacity`, `busy` | No host has room right now | Retry with the same idempotency key and a growing delay | A trial request never silently becomes a paid one. Paid credit does not make an exhausted trial available. See [the trial](./trial). ## Creation returns `starting` The SDKs and `npx withruntime sandbox create` wait for `running` for you. Over raw HTTP, send `Prefer: wait=60`, or read the sandbox with `?waitFor=running`. Wait for running before issuing commands. A command on a sandbox that is still starting waits up to 30 seconds, then answers `sandbox_not_ready`. If the sandbox stops before it is ready, its `stopReason` says why; report that failure with its sandbox id and request id. Do not start a new sandbox repeatedly without checking the first request's outcome. ## A sandbox stopped on its own Read its `stopReason`. `insufficient_funds` means the credit ran out; add credit on the account page. `lifetime_cap` means the sandbox reached its own `maxTotalCostMicros`. `spending_limit` means an owner-set spending limit stopped it, usually this agent's daily limit: see what is left with `GET /v1/limits` or `runtime limits`, and only an owner can raise it, on the account's keys page. Do not create replacements in a loop; the limit counts the last 24 hours. ## The request timed out A missing response is not proof that a command failed to run. Use the same idempotency key and identical input. The server answers the first result again instead of running it twice. The SDKs do this for you. If a command's outcome is still unknown, inspect its files and `processes` before repeating a side effect. ## The service returns 401, 403, 409, 429 or 5xx | Response | What to check | Safe next step | | ------------------ | ------------------------------------------------------------------- | -------------------------------------------------------------------------- | | 401 | Missing, expired or revoked key; wrong API origin | Check `npx withruntime whoami` or the secret-manager configuration | | 403 | Owner approval, key scope, account suspension or resource ownership | Confirm the account and permitted action; do not work around a refusal | | 409 | The resource's state: paused, stopped, not ready, or the trial busy | Resolve that state, then retry | | 422 | The idempotency key was used before with a different body | Same key, same body; or a new key for genuinely new work | | 429 | Request rate or concurrent work exceeded the server's bound | Respect `Retry-After`, add a growing delay, and reduce concurrent requests | | 5xx or no response | The write may already have reached the server | Retry identical input with the same idempotency key and inspect state | [API errors and retries](./api) describes the full contract. ## The command succeeded over HTTP but the task failed Inspect the command's exit code, standard error and truncation flags. HTTP success means the operation was handled, not that the program returned zero. Use `check: true` (`check=True` in Python) to raise on a non-zero exit. A timeout is a result with `timedOut: true`; raise `timeoutMs`, or run long jobs in the background and follow their output. ## A file operation fails File errors name the path and the reason: `file_not_found`, `is_a_directory`, `not_a_directory`, `permission_denied`. Paths are absolute; `/workspace` is home. Outside your own files, use `sudo` in a command. ## Dependencies cannot reach a server Check the sandbox's network rules (`npx withruntime sandbox network `) and the destination port. Keep the guest's proxy environment. A tool that opens raw sockets or ignores proxy configuration does not fit the public-web egress model; see [the sandbox environment](./sandbox-environment). Do not disable security protections to make a migration appear successful. ## The bill differs from an estimate Compare total CPU-seconds, provisioned memory, the quoted CPU floor and actual running duration. Include startup, dependency installation, retries and cleanup. Wait for settlement before equating reserved credit with a final charge. The dashboard groups daily and monthly settled service charges in UTC. A payment adds credit; it is not service usage. A reservation can lower available credit without being a final charge. Paused storage is a separate meter, so stopping compute does not prove all retained-storage charges have ended. ## A paused sandbox will not wake Inspect `pausedExpiresAt`, available credit and the error code. Wake needs room on the original host for CPU, memory, the full disk allowance and its next snapshot. A full host can refuse restoration while preserving the saved state. Do not delete it as a retry step. Missing memory images are an error, not an instruction to claim a fresh boot restored the previous process. Keep important outputs outside a sandbox before relying on long retention. See [storage and retention terms](./pricing) and [isolation limits](./security). ## Stop returned, but the sandbox is still stopping Stop is asynchronous. The SDKs wait for `stopped`; over HTTP, send `Prefer: wait=60` or read the sandbox with `?waitFor=stopped`. Compute ends after confirmed VM shutdown. Do not report cleanup complete just because the request was accepted. The host-side lease provides a bound, but is not proof that your cleanup already completed. ## MCP is connected but execution is still local MCP tools and a framework's built-in shell are different paths. Configure the framework's execution backend or replace its tool registration explicitly. Run a probe that prints the sandbox id and verifies a remote file round trip before claiming the migration is complete.