{"record":{"id":"e23ca55274f02200","repo":"paperclipai/paperclip","slug":"bridge-envelope-too-large","errorCode":null,"errorMessage":"Bridge envelope too large","messagePattern":"Bridge envelope too large","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/adapter-utils/src/sandbox-callback-bridge.ts","lineNumber":1072,"sourceCode":"      let raw: string;\n      try {\n        raw = await input.client.readTextFile(requestPath, readLimit);\n      } catch (error) {\n        // The gateway deletes a request file when its caller stops waiting\n        // (client-side timeout cleanup). A read that fails because the file is\n        // gone is that benign race, not a channel fault: confirm the file\n        // vanished and skip quietly instead of escalating into a recovery\n        // pass. A file that is still listed rethrows, so a real read fault\n        // keeps its existing handling.\n        const remaining = await input.client.listJsonFiles(directories.requestsDir).catch(() => null);\n        if (remaining !== null && !remaining.includes(fileName)) {\n          return;\n        }\n        throw error;\n      }\n      let request: SandboxCallbackBridgeRequest;\n      try {\n        if (Buffer.byteLength(raw) > maxEnvelopeBytes) throw new Error(\"Bridge envelope too large\");\n        request = JSON.parse(raw) as SandboxCallbackBridgeRequest;\n        decodeSandboxBridgeBody(request, maxBodyBytes);\n      } catch {\n        const requestId = fileName.replace(/\\.json$/i, \"\") || randomUUID();\n        await finalize({\n          id: requestId,\n          status: 400,\n          headers: { \"content-type\": \"application/json\" },\n          body: JSON.stringify({ error: \"Invalid bridge request payload.\" }),\n          completedAt: new Date().toISOString(),\n        });\n        return;\n      }\n\n      // Keep only the actual request allocation reserved while forwarding;\n      // an abandoned small request must not retain a maximum-sized reservation.\n      envelopeReadReservation.release();\n      if (!reservation.reserve(4 * Buffer.byteLength(raw) + 2 * Buffer.byteLength(request.body))) {","sourceCodeStart":1054,"sourceCodeEnd":1090,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/packages/adapter-utils/src/sandbox-callback-bridge.ts#L1054-L1090","documentation":"The bridge gateway's request poller reads each `.json` envelope and, before JSON-parsing it, checks Buffer.byteLength(raw) against maxEnvelopeBytes. If the raw envelope string is larger than the configured maximum it throws \"Bridge envelope too large\"; the enclosing catch converts this into a 400 \"Invalid bridge request payload.\" response file for the request id. This is the final in-process size gate after the earlier stat/read checks, protecting the host from oversized payloads before parse and body decode.","triggerScenarios":"A request envelope whose serialized JSON string exceeds maxEnvelopeBytes (6 * maxBodyBytes + 64KiB) reaches the poller — typically because the queue client's readTextFile did not enforce a byte limit (maxBytes undefined, or a client implementation lacking fileSize/read limits), so the raw string arrives whole and only this check catches it.","commonSituations":"Sandbox jobs posting very large bodies (big file uploads, huge diffs) through the callback bridge; misconfigured maxBodyBytes far below the payloads agents legitimately send; using a custom/older queue client without built-in read limits, so enforcement falls solely to this gateway-side check.","solutions":["Increase maxBodyBytes (and thereby maxEnvelopeBytes) in the bridge configuration to fit legitimate workloads.","Have producers enforce the limit client-side with encodeSandboxBridgeBody(body, maxBodyBytes) before writing the request, so oversized requests fail fast with a clear message instead of a generic 400.","Check the finalize response file for the request id — the gateway answers 400 \"Invalid bridge request payload.\"; correlate the rejected request with what the agent tried to send.","Use a queue client that supports fileSize/read limits so oversized envelopes are rejected earlier with the more specific 413 response.","Split or compress large payloads instead of sending them as a single envelope body."],"exampleFix":"// before: producer writes whatever it has, gateway rejects with a vague 400\nawait client.writeTextFile(requestPath, JSON.stringify({ body: bigPayload }));\n// after: fail fast with the codec's own limit\nconst envelope = encodeSandboxBridgeBody(bigPayload, maxBodyBytes); // throws early if too large\nawait client.writeTextFile(requestPath, JSON.stringify(envelope));","handlingStrategy":"try-catch","validationCode":"const raw = JSON.stringify(envelope);\nconst maxEnvelopeBytes = 6 * maxBodyBytes + 64 * 1024;\nif (Buffer.byteLength(raw) > maxEnvelopeBytes) throw new Error(`request envelope ${Buffer.byteLength(raw)}B exceeds ${maxEnvelopeBytes}B`);","typeGuard":null,"tryCatchPattern":"try {\n  if (Buffer.byteLength(raw) > maxEnvelopeBytes) throw new Error(\"Bridge envelope too large\");\n  request = JSON.parse(raw);\n  decodeSandboxBridgeBody(request, maxBodyBytes);\n} catch {\n  // gateway behaviour: reply 400 so the caller sees a definite failure\n  await finalize({ id: requestId, status: 400, body: JSON.stringify({ error: \"Invalid bridge request payload.\" }) });\n}","preventionTips":["Validate envelope size with encodeSandboxBridgeBody/Buffer.byteLength before writing the request file.","Prefer queue clients with fileSize/read limits so oversize is reported as 413, not a generic 400.","Set maxBodyBytes from measured real payload sizes, not guesses; leave headroom for JSON escaping.","Split or compress very large payloads instead of inflating the limit indefinitely.","Check the response envelope's error body to distinguish size rejection from malformed JSON."],"tags":["file-size","ipc","sandbox","limit"],"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-22T11:17:16.035Z"}