paperclipai/paperclip · error
Bridge envelope too large
Error message
Bridge envelope too large
What it means
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.
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.
Example fix
// before: producer writes whatever it has, gateway rejects with a vague 400
await client.writeTextFile(requestPath, JSON.stringify({ body: bigPayload }));
// after: fail fast with the codec's own limit
const envelope = encodeSandboxBridgeBody(bigPayload, maxBodyBytes); // throws early if too large
await client.writeTextFile(requestPath, JSON.stringify(envelope)); Defensive patterns
Strategy: try-catch
Validate before calling
const raw = JSON.stringify(envelope);
const maxEnvelopeBytes = 6 * maxBodyBytes + 64 * 1024;
if (Buffer.byteLength(raw) > maxEnvelopeBytes) throw new Error(`request envelope ${Buffer.byteLength(raw)}B exceeds ${maxEnvelopeBytes}B`); Try / catch
try {
if (Buffer.byteLength(raw) > maxEnvelopeBytes) throw new Error("Bridge envelope too large");
request = JSON.parse(raw);
decodeSandboxBridgeBody(request, maxBodyBytes);
} catch {
// gateway behaviour: reply 400 so the caller sees a definite failure
await finalize({ id: requestId, status: 400, body: JSON.stringify({ error: "Invalid bridge request payload." }) });
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.
Related errors
- Bridge envelope exceeded the configured size limit.
- Bridge response envelope changed while reading.
- Bridge response envelope exceeded the configured size limit.
- A sandbox command is required.
- ACPX module must be a bounded regular file
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18).
Data as JSON: /api/errors/e23ca55274f02200.
Report an issue: GitHub.
Appendix: source
Thrown at packages/adapter-utils/src/sandbox-callback-bridge.ts:1072
let raw: string;
try {
raw = await input.client.readTextFile(requestPath, readLimit);
} catch (error) {
// The gateway deletes a request file when its caller stops waiting
// (client-side timeout cleanup). A read that fails because the file is
// gone is that benign race, not a channel fault: confirm the file
// vanished and skip quietly instead of escalating into a recovery
// pass. A file that is still listed rethrows, so a real read fault
// keeps its existing handling.
const remaining = await input.client.listJsonFiles(directories.requestsDir).catch(() => null);
if (remaining !== null && !remaining.includes(fileName)) {
return;
}
throw error;
}
let request: SandboxCallbackBridgeRequest;
try {
if (Buffer.byteLength(raw) > maxEnvelopeBytes) throw new Error("Bridge envelope too large");
request = JSON.parse(raw) as SandboxCallbackBridgeRequest;
decodeSandboxBridgeBody(request, maxBodyBytes);
} catch {
const requestId = fileName.replace(/\.json$/i, "") || randomUUID();
await finalize({
id: requestId,
status: 400,
headers: { "content-type": "application/json" },
body: JSON.stringify({ error: "Invalid bridge request payload." }),
completedAt: new Date().toISOString(),
});
return;
}
// Keep only the actual request allocation reserved while forwarding;
// an abandoned small request must not retain a maximum-sized reservation.
envelopeReadReservation.release();
if (!reservation.reserve(4 * Buffer.byteLength(raw) + 2 * Buffer.byteLength(request.body))) {View on GitHub (pinned to 3f1d897a7c)