koala73/worldmonitor · error · RequestBodyTooLargeError

body-too-large

body-too-large

Error message

Request body exceeds ${maxBytes} bytes

What it means

readBoundedRequestBody() enforces a byte cap on incoming MCP/A2A request bodies. Before streaming the body it checks the Content-Length header, and if it declares more than maxBytes it cancels the stream early and throws RequestBodyTooLargeError (code 'body-too-large') without buffering any bytes. This is the fast-fail path for oversized payloads.

Source

Thrown at api/mcp/bounded-body.ts:80

 * oversized bodies are cancelled rather than buffered to completion, and the
 * unread tail is never copied into the returned buffer.
 */
export async function readBoundedRequestBody(
  request: Request,
  maxBytes: number,
): Promise<Uint8Array> {
  if (!Number.isFinite(maxBytes) || maxBytes < 0) {
    throw new TypeError('maxBytes must be a non-negative finite number');
  }

  const contentLengthRaw = request.headers.get('content-length');
  if (contentLengthRaw !== null && contentLengthRaw !== '') {
    const contentLength = Number(contentLengthRaw);
    if (Number.isFinite(contentLength) && contentLength > maxBytes) {
      if (request.body) {
        await request.body.cancel().catch(() => {});
      }
      throw new RequestBodyTooLargeError(maxBytes);
    }
  }

  if (!request.body) return new Uint8Array();

  const reader = request.body.getReader();
  const chunks: Uint8Array[] = [];
  let total = 0;
  try {
    while (true) {
      const { done, value } = await reader.read();
      if (done) break;
      if (!value || value.byteLength === 0) continue;
      total += value.byteLength;
      if (total > maxBytes) {
        await reader.cancel().catch(() => {});
        throw new RequestBodyTooLargeError(maxBytes);
      }

View on GitHub (pinned to 9361220cc0)

Solutions

  1. Shrink the client-side payload below maxBytes before sending (trim params, paginate large arrays).
  2. If the payload is legitimately large, raise the endpoint's configured maxBytes bound to an appropriate value and redeploy.
  3. If a proxy is inflating requests, fix the proxy to forward compact bodies and correct Content-Length.
  4. Confirm the client is not double-encoding (e.g. base64-in-JSON) which multiplies body size.

Example fix

// before
await fetch('/api/mcp', { method: 'POST', body: JSON.stringify(hugeParams) });
// after
const body = JSON.stringify(hugeParams);
if (new Blob([body]).size > MAX_BYTES) throw new Error('payload too large');
await fetch('/api/mcp', { method: 'POST', body, headers: { 'content-length': String(body.length) } });
Defensive patterns

Strategy: validation

Validate before calling

const bytes = new TextEncoder().encode(JSON.stringify(params)).length;
const MAX_BYTES = 1 << 20; // match endpoint config
if (bytes > MAX_BYTES) throw new Error(`payload ${bytes}B exceeds ${MAX_BYTES}B limit`);

Type guard

null

Try / catch

try {
  const body = await readBoundedRequestBody(request, { maxBytes });
} catch (err) {
  if (err instanceof RequestBodyTooLargeError) {
    return new Response(JSON.stringify({ error: 'body-too-large', maxBytes: err.maxBytes }), { status: 413 });
  }
  throw err;
}

Prevention

When it happens

Trigger: A client sends an HTTP request with a Content-Length header greater than the configured maxBytes to an endpoint using readBoundedRequestBody (e.g. api/mcp-proxy.ts, api/a2a.ts, api/docs-mcp.ts).

Common situations: An agent uploading a very large JSON-RPC params blob; a misbehaving client that doesn't chunk; a proxy forwarding an unbounded upstream body; integrations posting file attachments to a tool-call endpoint.

Related errors


AI-assisted analysis of koala73/worldmonitor@9361220cc0 (2026-09-01). Data as JSON: /api/errors/e810053d51b961c9. Report an issue: GitHub.