{"record":{"id":"b151ec2a5b22e24f","repo":"paperclipai/paperclip","slug":"the-bridge-host-reached-its-reserved-process-body","errorCode":null,"errorMessage":"The bridge host reached its reserved process body byte ceiling. Retry later.","messagePattern":"The bridge host reached its reserved process body byte ceiling\\. Retry later\\.","errorType":"exception","errorClass":"BridgeProcessCapacityError","httpStatus":null,"severity":"error","filePath":"packages/adapter-utils/src/execution-target.ts","lineNumber":1801,"sourceCode":"    return Buffer.alloc(0);\n  }\n\n  const reader = response.body.getReader();\n  const chunks: Buffer[] = [];\n  let totalBytes = 0;\n  while (true) {\n    const { done, value } = await reader.read();\n    if (done) break;\n    if (!value) continue;\n    const chunkBytes = value.byteLength;\n    totalBytes += chunkBytes;\n    if (totalBytes > maxBodyBytes) {\n      await reader.cancel().catch(() => undefined);\n      throw bridgeResponseBodyLimitError(maxBodyBytes);\n    }\n    if (reservation && !reservation.reserve(chunkBytes)) {\n      await reader.cancel().catch(() => undefined);\n      throw new BridgeProcessCapacityError();\n    }\n    chunks.push(Buffer.from(value));\n  }\n  if (reservation && !reservation.reserve(totalBytes)) {\n    await reader.cancel().catch(() => undefined);\n    throw new BridgeProcessCapacityError();\n  }\n  return Buffer.concat(chunks, totalBytes);\n}\n\nconst PROCESS_SESSION_PROXY_SCRIPT = \"paperclip-process-session-proxy.mjs\";\nconst PROCESS_SESSION_REMOTE_SCRIPT = \"paperclip-process-session-remote.mjs\";\n// The streamed variant writes its output frames to stdout, so it rides a\n// separate remote path. A sandbox can hold both scripts without the content\n// hash-skip gate thrashing when a run switches output mode.\nconst PROCESS_SESSION_REMOTE_STREAM_SCRIPT = \"paperclip-process-session-remote-stream.mjs\";\nconst PROCESS_SESSION_AUTH_TIMEOUT_MS = 5_000;\n// The bounded budget `stop()` waits for the wrapper's `shutdownAck` event","sourceCodeStart":1783,"sourceCodeEnd":1819,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/adapter-utils/src/execution-target.ts#L1783-L1819","documentation":"While reading a bridge-forwarded response body stream, each chunk is reserved against a shared per-process byte ledger. This error is thrown when an incoming chunk would push the retained bytes past the configured maxBodyBytes limit, protecting the bridge host from unbounded response bodies.","triggerScenarios":"readBridgeForwardResponseBody streams a response whose accumulated totalBytes exceeds maxBodyBytes; the stream is cancelled and bridgeResponseBodyLimitError(maxBodyBytes) is thrown. Happens on any forwarded HTTP response larger than the configured ceiling.","commonSituations":"Agent requests a large file/download through the bridge; logs or API responses unexpectedly huge; maxBodyBytes configured too low for legitimate workloads; a looping endpoint streaming unbounded data.","solutions":["Increase the bridge's maxBodyBytes / body-limit configuration to accommodate expected payloads.","Chunk large downloads so no single forwarded response exceeds the limit.","Fix the upstream endpoint producing oversized responses if it is unexpectedly large.","Check for runaway/looping generation inflating responses beyond intended size."],"exampleFix":"// before: single large forwarded response\nconst body = await readBridgeForwardResponseBody(stream, { maxBodyBytes: 1_048_576 }, reservation);\n// after: paginate or stream in bounded pieces\nfor await (const piece of paginatedFetch(url, { pageSize: 64 * 1024 })) {\n  const body = await readBridgeForwardResponseBody(piece, { maxBodyBytes: 1_048_576 }, reservation);\n  consume(body);\n}","handlingStrategy":"validation","validationCode":"const contentLength = Number(responseHeaders[\"content-length\"] ?? 0);\nif (contentLength > maxBodyBytes) throw new Error(`response of ${contentLength} bytes exceeds bridge limit ${maxBodyBytes}; use chunked download`);","typeGuard":"function bodyWithinLimit(size: number, maxBodyBytes: number): boolean {\n  return size > 0 && size <= maxBodyBytes;\n}","tryCatchPattern":"try {\n  const body = await readBridgeForwardResponseBody(stream, bounds, reservation);\n} catch (err) {\n  if (String(err.message).includes(\"byte ceiling\")) {\n    throw new Error(\"response too large for bridge; paginate or raise maxBodyBytes\", { cause: err });\n  }\n  throw err;\n}","preventionTips":["Set maxBodyBytes above the largest legitimate forwarded response.","Use ranged/chunked downloads for large artifacts instead of one forwarded body.","Alert on endpoints whose response sizes approach the limit.","Cap agent-side request sizes before they hit the bridge."],"tags":["http","limit","bridge","streaming"],"backgroundTag":"payload-too-large","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}