paperclipai/paperclip · error
Cloudflare sandbox bridge request timed out after ${requestT
Error message
Cloudflare sandbox bridge request timed out after ${requestTimeoutMs}ms. What it means
Thrown by the Cloudflare bridge client's `requestJson` (bridge-client.ts:136-138) when the `AbortController` fires before the bridge responds. The request timeout is `resolveRequestTimeoutMs(config, path, init)`; for `/exec` it is the max of the configured `bridgeRequestTimeoutMs` and the body's requested `timeoutMs`, otherwise it is the configured default. The AbortError is converted into this plain Error.
Source
Thrown at packages/plugins/sandbox-providers/cloudflare/src/bridge-client.ts:136
});
const body = await parseJson(response);
if (!response.ok) {
const errorBody = isRecord(body) ? body as BridgeErrorBody : {};
throw new CloudflareBridgeError({
status: response.status,
code: typeof errorBody.error === "string" ? errorBody.error : null,
message:
typeof errorBody.message === "string" && errorBody.message.trim().length > 0
? errorBody.message
: `Cloudflare sandbox bridge request failed with HTTP ${response.status}.`,
details: errorBody.details,
});
}
return body as T;
} catch (error) {
if (error instanceof CloudflareBridgeError) throw error;
if ((error as { name?: string } | null)?.name === "AbortError") {
throw new Error(
`Cloudflare sandbox bridge request timed out after ${requestTimeoutMs}ms.`,
);
}
throw error;
} finally {
clearTimeout(timeout);
}
}
async function requestResponse(
config: CloudflareDriverConfig,
path: string,
init: RequestInit,
extraHeaders: BridgeClientHeaders = {},
): Promise<Response> {
const controller = new AbortController();
const requestTimeoutMs = resolveRequestTimeoutMs(config, path, init);
const timeout = setTimeout(() => controller.abort(), requestTimeoutMs);View on GitHub (pinned to 67001ec6eb)
Solutions
- Raise `bridgeRequestTimeoutMs` in the driver config, or pass a larger `timeoutMs` in the exec body.
- For long-running commands, use the streaming exec path (supply `onOutput`) so the response is an SSE stream not bounded by the JSON request timeout.
- Retry transient network-induced timeouts.
Example fix
// before
await client.execute({ providerLeaseId, command: "npm run build", timeoutMs: 5000 });
// after
await client.execute({ providerLeaseId, command: "npm run build", timeoutMs: 60000 }, headers, { onOutput: console.log }); Defensive patterns
Strategy: retry
Validate before calling
// Raise the configured request timeout for long commands. config.bridgeRequestTimeoutMs = Math.max(config.bridgeRequestTimeoutMs ?? 30000, 120000);
Type guard
function isBridgeTimeout(e: unknown): boolean {
return e instanceof Error && /bridge request timed out/.test(e.message);
} Try / catch
async function execWithRetry(client, body, headers) {
for (let i = 0; i < 2; i++) {
try {
return await client.execute({ ...body, timeoutMs: 60000 }, headers);
} catch (err) {
if (isBridgeTimeout(err) && i === 0) continue;
throw err;
}
}
} Prevention
- Use the streaming exec path (onOutput) for long-running commands.
- Size bridgeRequestTimeoutMs to the slowest legitimate command.
- Retry once on transient network timeouts.
When it happens
Trigger: Any JSON bridge call takes longer than the resolved request timeout: a long-running non-streaming `/exec` command, a slow `/leases/acquire` cold start, or network latency/edge stalls between the driver and the bridge Worker.
Common situations: Running a synchronous command via `/exec` without `streamOutput` that legitimately runs long; bridge or Cloudflare edge congestion; or `bridgeRequestTimeoutMs` configured too low for the workload.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- ${action} timed out: ${result.stderr.trim()}
- Cloudflare sandbox bridge request failed with HTTP ${respons
- Cloudflare sandbox bridge streaming response had no body.
- Cloudflare sandbox bridge streaming response ended without a
- stop sandbox callback bridge timed out${detail ? `: ${detail
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/e6394f108c280b79.
Report an issue: GitHub.