{"record":{"id":"2724bdb975ec2716","repo":"paperclipai/paperclip","slug":"bridge-response-body-exceeded-the-configured-size","errorCode":null,"errorMessage":"Bridge response body exceeded the configured size limit of ${maxBodyBytes} bytes.","messagePattern":"Bridge response body exceeded the configured size limit of (.+?) bytes\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/adapter-utils/src/sandbox-callback-bridge.ts","lineNumber":734,"sourceCode":"\n    const denialReason = await authorizeRequest(request);\n    if (denialReason) {\n      await writeBridgeResponse(input.client, requestPath, responsePath, {\n        id: request.id,\n        status: 403,\n        headers: { \"content-type\": \"application/json\" },\n        body: JSON.stringify({ error: denialReason }),\n        completedAt: new Date().toISOString(),\n      });\n      await input.client.remove(requestPath);\n      return;\n    }\n\n    try {\n      const result = await input.handleRequest(request);\n      const responseBody = result.body ?? \"\";\n      if (Buffer.byteLength(responseBody, \"utf8\") > maxBodyBytes) {\n        throw new Error(`Bridge response body exceeded the configured size limit of ${maxBodyBytes} bytes.`);\n      }\n      await writeBridgeResponse(input.client, requestPath, responsePath, {\n        id: request.id,\n        status: result.status,\n        headers: result.headers ?? {},\n        body: responseBody,\n        completedAt: new Date().toISOString(),\n      });\n    } catch (error) {\n      console.warn(\n        `[paperclip] sandbox callback bridge handler failed for ${request.id}: ${error instanceof Error ? error.message : String(error)}`,\n      );\n      await writeBridgeResponse(input.client, requestPath, responsePath, {\n        id: request.id,\n        status: 502,\n        headers: { \"content-type\": \"application/json\" },\n        body: JSON.stringify({\n          error: error instanceof Error ? error.message : String(error),","sourceCodeStart":716,"sourceCodeEnd":752,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/packages/adapter-utils/src/sandbox-callback-bridge.ts#L716-L752","documentation":"Thrown inside the bridge request handler after handleRequest returns, when Buffer.byteLength(responseBody, \"utf8\") exceeds maxBodyBytes. The default limit is 256 KiB (DEFAULT_BRIDGE_MAX_BODY_BYTES = 256 * 1024); it can be overridden per bridge instance via the maxBodyBytes option. The throw is caught by the surrounding try/catch at sandbox-callback-bridge.ts:743, which writes a 502 response back to the caller with the error message in the body — so the caller sees a 502, not a stack trace, and the request file is removed.","triggerScenarios":"A bridge handleRequest that returns a large body — verbose logs, full file dumps, large JSON payloads, base64-encoded binary. The check at sandbox-callback-bridge.ts:733-735 measures UTF-8 bytes after result.body ?? \"\", so multi-byte content (CJK, emoji) counts as more than its character length.","commonSituations":"Endpoints that stream or snapshot large outputs (build logs, screenshot base64, directory listings, model responses with long completions). Production runs that work fine until a single large payload trips the cap; defaults fit typical control messages but not bulk file transfer.","solutions":["Reduce response body size in handleRequest: truncate, paginate, or stream instead of returning the full payload.","Raise the limit explicitly when constructing the bridge: startSandboxCallbackBridgePoller({ ..., maxBodyBytes: 2 * 1024 * 1024 }) for 2 MiB.","Inspect the resulting 502 response body the caller receives — it will contain this exact message, confirming the size cap as the cause.","If payloads are routinely large, switch the bridge to a side-channel transfer (write to a synced file, return a path) instead of inlining bytes in the JSON response."],"exampleFix":"// before\nstartSandboxCallbackBridgePoller({\n  client, handleRequest, directories,\n  // default maxBodyBytes = 256 KiB\n});\n// handler returns a 2 MiB base64 payload -> 502\n\n// after\nstartSandboxCallbackBridgePoller({\n  client, handleRequest, directories,\n  maxBodyBytes: 4 * 1024 * 1024,\n});","handlingStrategy":"validation","validationCode":"const MAX_BODY_BYTES = 256 * 1024; // mirror DEFAULT_BRIDGE_MAX_BODY_BYTES\nfunction assertResponseBodySize(body: string, limit = MAX_BODY_BYTES): void {\n  if (Buffer.byteLength(body, \"utf8\") > limit) {\n    throw new Error(`Response body ${Buffer.byteLength(body, \"utf8\")} bytes exceeds limit ${limit}; paginate, truncate, or raise maxBodyBytes`);\n  }\n}\n\n// inside handleRequest, before returning:\nassertResponseBodySize(result.body ?? \"\");","typeGuard":null,"tryCatchPattern":"// The bridge already converts this throw into a 502 response for the caller.\n// In the handler, you can preempt it:\nconst body = await buildResponse(request);\nif (Buffer.byteLength(body, \"utf8\") > (maxBodyBytes ?? 256 * 1024)) {\n  return { status: 413, headers: { \"content-type\": \"application/json\" }, body: JSON.stringify({ error: \"response too large\" }) };\n}","preventionTips":["Keep bridge responses under 256 KiB; offload larger payloads to a synced file and return a path reference.","If you need more, set maxBodyBytes explicitly when constructing the bridge.","Measure UTF-8 bytes (Buffer.byteLength), not string length — multi-byte content inflates faster than expected.","Add a unit test that asserts every handleRequest response stays under the configured cap."],"tags":["bridge","config-validation","limits","callback-bridge","response-size"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}