{"record":{"id":"da705c89ba68cbfa","repo":"paperclipai/paperclip","slug":"bridge-body-exceeded-the-configured-size-limit","errorCode":null,"errorMessage":"Bridge body exceeded the configured size limit.","messagePattern":"Bridge body exceeded the configured size limit\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/adapter-utils/src/sandbox-callback-bridge-body.ts","lineNumber":13,"sourceCode":"export interface SandboxCallbackBridgeBody {\n  body: string;\n  /** Omitted by older queue peers, whose bodies are UTF-8 text. */\n  bodyEncoding?: \"utf8\" | \"base64\";\n}\n\n/** JSON can escape each input byte as six characters. Metadata is bounded too. */\nexport function sandboxBridgeEnvelopeLimit(maxBodyBytes: number): number {\n  return 6 * maxBodyBytes + 64 * 1024;\n}\n\nexport function encodeSandboxBridgeBody(body: string | Buffer, maxBodyBytes: number): SandboxCallbackBridgeBody {\n  if (Buffer.byteLength(body) > maxBodyBytes) throw new Error(\"Bridge body exceeded the configured size limit.\");\n  return Buffer.isBuffer(body) ? { body: body.toString(\"base64\"), bodyEncoding: \"base64\" } : { body };\n}\n\n/** Self-contained so the same decoder can be embedded in the remote gateway. */\nexport function decodeSandboxBridgeBody(envelope: SandboxCallbackBridgeBody, maxBodyBytes: number): Buffer {\n  if (!envelope || typeof envelope.body !== \"string\") throw new Error(\"Invalid bridge body.\");\n  if (envelope.bodyEncoding === undefined || envelope.bodyEncoding === \"utf8\") {\n    if (Buffer.byteLength(envelope.body, \"utf8\") > maxBodyBytes) throw new Error(\"Bridge body exceeded the configured size limit.\");\n    return Buffer.from(envelope.body, \"utf8\");\n  }\n  if (envelope.bodyEncoding !== \"base64\") throw new Error(\"Unsupported bridge body encoding.\");\n  const value = envelope.body;\n  if (value.length > 4 * Math.ceil(maxBodyBytes / 3)) throw new Error(\"Bridge body exceeded the configured size limit.\");\n  // Buffer.from is permissive; reject malformed input before allocating bytes.\n  if (value.length % 4 !== 0 || /[^A-Za-z0-9+/=]/.test(value) || !/^[A-Za-z0-9+/]*={0,2}$/.test(value)) {\n    throw new Error(\"Invalid bridge base64 body.\");\n  }\n  const bytes = Buffer.from(value, \"base64\");","sourceCodeStart":1,"sourceCodeEnd":31,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/packages/adapter-utils/src/sandbox-callback-bridge-body.ts#L1-L31","documentation":"encodeSandboxBridgeBody serializes a callback body for transport through the sandbox bridge and enforces a hard byte limit (maxBodyBytes). If Buffer.byteLength(body) exceeds that limit it throws instead of silently truncating, because downstream decoders and the envelope-size math (6x expansion + 64KiB metadata slack) assume bounded bodies.","triggerScenarios":"Calling encodeSandboxBridgeBody(body, maxBodyBytes) with a string or Buffer whose UTF-8 byte length exceeds maxBodyBytes — e.g. large response payloads from process output, file contents, or accumulated logs routed through responseBody.","commonSituations":"Raising agent output limits without raising the bridge's configured max body size; an agent dumps a big file or verbose log into a callback; a caller passes an entire HTTP response body assuming the bridge will chunk it.","solutions":["Measure the payload first (`Buffer.byteLength(body)`) and raise maxBodyBytes in the bridge configuration if the larger size is legitimate.","Truncate or chunk the payload at the call site before encoding (e.g. cap captured output to the configured limit).","Compress or summarize large content (base64 of compressed bytes still counts — reduce source bytes instead).","If huge bodies are expected regularly, switch the transport to a file/blob reference passed by path instead of inlining the body."],"exampleFix":"// before\nconst envelope = encodeSandboxBridgeBody(hugeLog, maxBodyBytes); // throws\n// after\nconst clipped = hugeLog.length > maxBodyBytes ? hugeLog.slice(0, maxBodyBytes) : hugeLog;\nconst envelope = encodeSandboxBridgeBody(clipped, maxBodyBytes);","handlingStrategy":"try-catch","validationCode":"const bytes = Buffer.isBuffer(body) ? body.length : Buffer.byteLength(body);\nif (bytes > maxBodyBytes) body = body.slice(0, maxBodyBytes); // or truncate the string first","typeGuard":"function withinBridgeLimit(body: string | Buffer, maxBodyBytes: number): boolean {\n  return Buffer.byteLength(body) <= maxBodyBytes;\n}","tryCatchPattern":"try {\n  envelope = encodeSandboxBridgeBody(body, maxBodyBytes);\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"size limit\")) {\n    envelope = encodeSandboxBridgeBody(truncateToBytes(body, maxBodyBytes), maxBodyBytes);\n  } else throw err;\n}","preventionTips":["Bound captured process output/file reads to maxBodyBytes at the source.","Keep producer and gateway maxBodyBytes configuration in sync.","Use sandboxBridgeEnvelopeLimit() to size any upstream envelope/queue limits.","Prefer externalizing large payloads (file/blob reference) over inlining them."],"tags":["payload-size","limit","sandbox-bridge","validation"],"backgroundTag":"payload-too-large","analyzedSha":"3f1d897a7c018d76563a21c6e39c3c9b03933622","analyzedAt":"2026-09-18T08:03:59.046Z","contentChangedAt":"2026-09-18T08:03:59.046Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}