paperclipai/paperclip · error
${action} timed out: ${result.stderr.trim()}
Error message
${action} timed out: ${result.stderr.trim()} What it means
Thrown by the Cloudflare bridge's `requireZeroExit` (routes.ts:118) when a lease-utility command (mkdir workspace, write/verify sentinel) returns `timedOut: true`. The wrapper `executeInSandbox` converts SDK timeout errors into a result with `timedOut: true` and a stderr message, and `requireZeroExit` surfaces that as a timed-out action error with the stderr detail.
Source
Thrown at packages/plugins/sandbox-providers/cloudflare/bridge-template/src/routes.ts:118
},
command: string,
args: string[],
cwd = "/",
) {
return await executeInSandbox({
sandbox,
command,
args,
cwd,
timeoutMs: options.timeoutMs,
sessionStrategy: options.sessionStrategy,
sessionId: options.sessionId,
});
}
function requireZeroExit(action: string, result: { exitCode: number | null; timedOut: boolean; stderr: string }) {
if (result.timedOut) {
throw new Error(`${action} timed out: ${result.stderr.trim()}`);
}
if (result.exitCode !== 0) {
throw new Error(
`${action} failed with exit code ${result.exitCode ?? "null"}${result.stderr.trim() ? `: ${result.stderr.trim()}` : ""}`,
);
}
}
async function ensureWorkspace(
sandbox: CloudflareSandbox,
options: {
remoteCwd: string;
sessionStrategy: SessionStrategy;
sessionId: string;
timeoutMs: number;
},
) {
const result = await execLeaseUtility(sandbox, options, "mkdir", ["-p", options.remoteCwd], "/");View on GitHub (pinned to 67001ec6eb)
Solutions
- Increase `timeoutMs` in the acquire/probe/resume request body to accommodate sandbox cold-start.
- Retry the lease acquire/resume — cold-start latency is often transient on the second attempt.
- If persistent, check Cloudflare sandbox service health and the bridge deployment region.
Example fix
// before
{ method: "POST", body: JSON.stringify({ environmentId, runId, timeoutMs: 5000 }) }
// after
{ method: "POST", body: JSON.stringify({ environmentId, runId, timeoutMs: 60000 }) } Defensive patterns
Strategy: retry
Validate before calling
// Choose a timeout that tolerates cold start before the request.
function leaseTimeoutMs(attempt) {
const base = 30000;
return attempt === 0 ? base : base * (attempt + 1); // 30s, 60s, 90s
} Try / catch
async function acquireWithRetry(client, body, attempts = 3) {
let lastErr;
for (let i = 0; i < attempts; i++) {
try {
return await client.acquireLease({ ...body, timeoutMs: leaseTimeoutMs(i) });
} catch (err) {
lastErr = err;
if (err instanceof Error && err.message.includes("timed out")) continue;
throw err;
}
}
throw lastErr;
} Prevention
- Set timeoutMs large enough for sandbox cold start (>= 30s).
- Retry acquire/resume once or twice on timeout — cold start is transient.
- Monitor bridge Worker/edge latency; warm leases with keepAlive.
When it happens
Trigger: During `/leases/acquire`, `/leases/resume`, or `/probe`, an internal setup command (`mkdir -p <remoteCwd>`, sentinel write/verify) exceeds the `timeoutMs` window configured for the request (default `DEFAULT_TIMEOUT_MS`). Slow/cold-starting sandboxes or a frozen filesystem make the SDK's exec timeout trip.
Common situations: Cloudflare sandbox cold start adds latency that pushes the first mkdir/sentinel past the default timeout; an overloaded Workers/edge environment; or the caller set a very low `timeoutMs`.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- ${action} failed with exit code ${result.exitCode ?? "null"}
- Cloudflare sandbox bridge request timed out after ${requestT
- stop sandbox callback bridge timed out${detail ? `: ${detail
- Cloudflare sandbox bridge request failed with HTTP ${respons
- Cloudflare sandbox bridge streaming response had no body.
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/6b09cf4265481afd.
Report an issue: GitHub.