Hmbown/CodeWhale · warning · FormBodyError

payload too large

Error message

payload too large

What it means

FormBodyError with HTTP 413, thrown while streaming the body: the running byte total exceeded the maxBytes the caller passed. The reader is cancelled first (a cancellation failure is deliberately swallowed) so the remainder of the oversized upload is drained and the limit stays enforced.

Source

Thrown at web/lib/bounded-form.ts:41

    if (Number(rawLength) > maxBytes) throw new FormBodyError(413, "payload too large");
  }

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

  const reader = request.body.getReader();
  const chunks: Uint8Array[] = [];
  let total = 0;
  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    total += value.byteLength;
    if (total > maxBytes) {
      try {
        await reader.cancel("payload too large");
      } catch {
        // A source cancellation error must not obscure the enforced size limit.
      }
      throw new FormBodyError(413, "payload too large");
    }
    chunks.push(value);
  }

  const bytes = new Uint8Array(total);
  let offset = 0;
  for (const chunk of chunks) {
    bytes.set(chunk, offset);
    offset += chunk.byteLength;
  }
  return new URLSearchParams(new TextDecoder().decode(bytes));
}

View on GitHub (pinned to 8880682c63)

Solutions

  1. Reduce the submitted data (trim fields, shorten text)
  2. Raise the maxBytes argument for that route if larger input is legitimately expected
  3. Split the submission or move large content to an object-storage upload flow

Example fix

// before
const params = await readBoundedUrlEncodedForm(request, 8 * 1024);

// after - raise the route's limit to match real input sizes
const params = await readBoundedUrlEncodedForm(request, 64 * 1024);
Defensive patterns

Strategy: validation

Validate before calling

const bodyText = new URLSearchParams(Object.fromEntries(new FormData(formEl))).toString();
if (bodyText.length > MAX_BYTES) {
  showToast(`Submission is ${bodyText.length} bytes; limit is ${MAX_BYTES}. Shorten the text.`);
  return;
}
await fetch(action, { method: 'POST', body: bodyText });

Try / catch

try {
  const params = await readBoundedUrlEncodedForm(request, MAX_BYTES);
} catch (err) {
  if (err instanceof FormBodyError && err.status === 413) {
    return new Response(`payload too large, limit ${MAX_BYTES} bytes`, { status: 413 });
  }
  throw err;
}

Prevention

When it happens

Trigger: A urlencoded body larger than the route's maxBytes; chunked uploads with no Content-Length so only the streaming counter catches them; clients that under-report Content-Length.

Common situations: Long textarea submissions (pasted logs) against a small 8-16 KB limit; a product decision to allow bigger fields without raising the route's maxBytes argument.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/061ca8be6eb47b9f. Report an issue: GitHub.