{"record":{"id":"3cd814f7a4c9e839","repo":"paperclipai/paperclip","slug":"cloudflare-sandbox-bridge-request-failed-with-http","errorCode":null,"errorMessage":"Cloudflare sandbox bridge request failed with HTTP ${response.status}.","messagePattern":"Cloudflare sandbox bridge request failed with HTTP (.+?)\\.","errorType":"exception","errorClass":"CloudflareBridgeError","httpStatus":null,"severity":"error","filePath":"packages/plugins/sandbox-providers/cloudflare/src/bridge-client.ts","lineNumber":122,"sourceCode":"  path: string,\n  init: RequestInit,\n  extraHeaders: BridgeClientHeaders = {},\n): Promise<T> {\n  const controller = new AbortController();\n  const requestTimeoutMs = resolveRequestTimeoutMs(config, path, init);\n  const timeout = setTimeout(() => controller.abort(), requestTimeoutMs);\n  const baseUrl = config.bridgeBaseUrl.replace(/\\/+$/, \"\");\n\n  try {\n    const response = await fetch(`${baseUrl}${path}`, {\n      ...init,\n      headers: buildHeaders(config, extraHeaders),\n      signal: controller.signal,\n    });\n    const body = await parseJson(response);\n    if (!response.ok) {\n      const errorBody = isRecord(body) ? body as BridgeErrorBody : {};\n      throw new CloudflareBridgeError({\n        status: response.status,\n        code: typeof errorBody.error === \"string\" ? errorBody.error : null,\n        message:\n          typeof errorBody.message === \"string\" && errorBody.message.trim().length > 0\n            ? errorBody.message\n            : `Cloudflare sandbox bridge request failed with HTTP ${response.status}.`,\n        details: errorBody.details,\n      });\n    }\n    return body as T;\n  } catch (error) {\n    if (error instanceof CloudflareBridgeError) throw error;\n    if ((error as { name?: string } | null)?.name === \"AbortError\") {\n      throw new Error(\n        `Cloudflare sandbox bridge request timed out after ${requestTimeoutMs}ms.`,\n      );\n    }\n    throw error;","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/packages/plugins/sandbox-providers/cloudflare/src/bridge-client.ts#L104-L140","documentation":"Thrown by the Cloudflare bridge client's `requestJson` (bridge-client.ts:122-128) as a `CloudflareBridgeError` when the bridge returns a non-2xx HTTP status and the JSON error body either has no `message` field or an empty/whitespace one. The literal `HTTP ${response.status}` is the fallback so the caller still sees the status code; a non-empty server `message` would override it.","triggerScenarios":"Any JSON bridge call (`/health`, `/probe`, `/leases/*`, non-streaming `/exec`) gets a 4xx/5xx from the bridge Worker — e.g. 401 (bad bearer token), 400 `invalid_request`, 409 `sandbox_state_lost`, 404 route mismatch — and the response body omits a usable message string.","commonSituations":"Wrong/missing `bridgeAuthToken` (401), malformed request body (400), resuming a lease whose sandbox state was evicted (409), or a bridge deployment that returns plain status codes without a JSON message field.","solutions":["Inspect the `CloudflareBridgeError.status` and `.code` fields (not just the message) to determine the real failure class.","For 401, verify `config.bridgeAuthToken` matches the bridge's `BRIDGE_AUTH_TOKEN`.","For 409 on resume, re-acquire the lease instead of resuming.","For 400, validate the request body shape before sending."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"import { CloudflareBridgeError } from \"@paperclipai/cloudflare-bridge-client\";\nfunction isBridgeError(e: unknown, status?: number): e is CloudflareBridgeError {\n  return e instanceof CloudflareBridgeError && (status === undefined || e.status === status);\n}","tryCatchPattern":"try {\n  await client.health();\n} catch (err) {\n  if (err instanceof CloudflareBridgeError) {\n    if (err.status === 401) refreshBridgeToken();\n    else if (err.status === 400) fixRequestBody();\n    else throw err;\n  } else throw err;\n}","preventionTips":["Always check CloudflareBridgeError.status and .code rather than the message string.","Keep bridgeAuthToken aligned with the bridge's BRIDGE_AUTH_TOKEN.","Validate request body shape (providerLeaseId, command) before sending."],"tags":["cloudflare","sandbox","bridge","network","http-error"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}