{"record":{"id":"ba822031af3fb89a","repo":"paperclipai/paperclip","slug":"bridge-response-body-exceeded-the-configured-size-limit","errorCode":null,"errorMessage":"Bridge response body exceeded the configured size limit.","messagePattern":"Bridge response body exceeded the configured size limit\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/adapter-utils/src/sandbox-callback-bridge.ts","lineNumber":1129,"sourceCode":"      // retry, so do not run the mutation; the retry then applies it once. When\n      // the handler claims first, the recovery path leaves the request alone and\n      // the handler writes the real response.\n      if (!claimForHandler()) {\n        return;\n      }\n\n      // Build the response, then finalize once. The handler already holds the\n      // claim, so `finalize` writes the real response.\n      let response: SandboxCallbackBridgeResponse;\n      let handlerReturned = false;\n      try {\n        const { bodyEncoding, ...forwardRequest } = request;\n        const result = await input.handleRequest({ ...forwardRequest,\n          body: bodyEncoding === \"base64\" ? decodeSandboxBridgeBody(request, maxBodyBytes) : request.body,\n        }, { signal: guard.controller.signal, reservation });\n        handlerReturned = true;\n        const responseBytes = Buffer.byteLength(result.body ?? \"\");\n        if (responseBytes > maxBodyBytes) throw new Error(\"Bridge response body exceeded the configured size limit.\");\n        if (!reservation.reserve(4 * sandboxBridgeEnvelopeLimit(responseBytes))) {\n          throw new Error(\"Bridge host response body capacity is busy.\");\n        }\n        const responseBody = encodeSandboxBridgeBody(result.body ?? \"\", maxBodyBytes);\n        response = {\n          id: request.id,\n          status: result.status,\n          headers: result.headers ?? {},\n          ...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        // Tell a worker abort apart from a normal handler failure. The recovery\n        // path aborts `guard.controller` when the per-iteration timeout or the\n        // watchdog fires. The abort reaches this catch only after the handler","sourceCodeStart":1111,"sourceCodeEnd":1147,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/packages/adapter-utils/src/sandbox-callback-bridge.ts#L1111-L1147","documentation":"The sandbox callback bridge handler produced a response whose body is larger than maxBodyBytes, the configured per-message body cap for the bridge. The bridge enforces this before encoding the response so a single oversized handler reply cannot balloon the process memory ledger or the on-disk envelope. The error is thrown inside the host-side handler wrapper and surfaces to the sandbox caller as a bridge handler failure.","triggerScenarios":"A registered input.handleRequest callback returns { body } whose Buffer.byteLength exceeds maxBodyBytes for a sandbox bridge request.","commonSituations":"A handler echoes back a large file, log blob, or generated artifact; maxBodyBytes was lowered in config while existing handlers still return big payloads; base64-encoded responses inflate ~33% past the raw limit.","solutions":["Reduce the response body returned by the handler (paginate, truncate, or stream to a file and return a reference).","Raise the bridge's maxBodyBytes configuration to fit the largest legitimate handler response.","Return a non-2xx status with a small JSON error body instead of embedding the large payload."],"exampleFix":"// before\nreturn { status: 200, body: largeFileBuffer.toString(\"utf8\") };\n// after\nif (largeFileBuffer.byteLength > maxBodyBytes) {\n  return { status: 413, body: JSON.stringify({ error: \"payload too large\", savedTo: scratchPath }) };\n}\nreturn { status: 200, body: largeFileBuffer.toString(\"utf8\") };","handlingStrategy":"validation","validationCode":"const bytes = Buffer.byteLength(result.body ?? \"\");\nif (bytes > maxBodyBytes) return { status: 413, body: JSON.stringify({ error: \"response too large\" }) };","typeGuard":"const fitsBridgeLimit = (body: unknown, max: number): boolean =>\n  body == null || Buffer.byteLength(typeof body === \"string\" ? body : String(body)) <= max;","tryCatchPattern":"try { return await bridge.dispatch(req); } catch (e) { if (e.message.includes(\"size limit\")) return { status: 413, body: \"response too large\" }; throw e; }","preventionTips":["Truncate or chunk handler responses before returning them","Keep maxBodyBytes in sync with the largest known handler output","Return file references instead of inline blobs for big payloads","Account for base64 encoding overhead (~33%) when sizing bodies"],"tags":["sandbox","size-limit","payload-too-large","bridge"],"backgroundTag":"file-size-limit-exceeded","analyzedSha":"3f1d897a7c018d76563a21c6e39c3c9b03933622","analyzedAt":"2026-09-18T08:03:59.046Z","contentChangedAt":"2026-09-18T08:03:59.046Z","schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}