{"record":{"id":"061ca8be6eb47b9f","repo":"Hmbown/CodeWhale","slug":"payload-too-large","errorCode":null,"errorMessage":"payload too large","messagePattern":"payload too large","errorType":"http","errorClass":"FormBodyError","httpStatus":413,"severity":"warning","filePath":"web/lib/bounded-form.ts","lineNumber":41,"sourceCode":"    if (Number(rawLength) > maxBytes) throw new FormBodyError(413, \"payload too large\");\n  }\n\n  if (!request.body) return new URLSearchParams();\n\n  const reader = request.body.getReader();\n  const chunks: Uint8Array[] = [];\n  let total = 0;\n  while (true) {\n    const { done, value } = await reader.read();\n    if (done) break;\n    total += value.byteLength;\n    if (total > maxBytes) {\n      try {\n        await reader.cancel(\"payload too large\");\n      } catch {\n        // A source cancellation error must not obscure the enforced size limit.\n      }\n      throw new FormBodyError(413, \"payload too large\");\n    }\n    chunks.push(value);\n  }\n\n  const bytes = new Uint8Array(total);\n  let offset = 0;\n  for (const chunk of chunks) {\n    bytes.set(chunk, offset);\n    offset += chunk.byteLength;\n  }\n  return new URLSearchParams(new TextDecoder().decode(bytes));\n}\n","sourceCodeStart":23,"sourceCodeEnd":54,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/web/lib/bounded-form.ts#L23-L54","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Reduce the submitted data (trim fields, shorten text)","Raise the maxBytes argument for that route if larger input is legitimately expected","Split the submission or move large content to an object-storage upload flow"],"exampleFix":"// before\nconst params = await readBoundedUrlEncodedForm(request, 8 * 1024);\n\n// after - raise the route's limit to match real input sizes\nconst params = await readBoundedUrlEncodedForm(request, 64 * 1024);","handlingStrategy":"validation","validationCode":"const bodyText = new URLSearchParams(Object.fromEntries(new FormData(formEl))).toString();\nif (bodyText.length > MAX_BYTES) {\n  showToast(`Submission is ${bodyText.length} bytes; limit is ${MAX_BYTES}. Shorten the text.`);\n  return;\n}\nawait fetch(action, { method: 'POST', body: bodyText });","typeGuard":null,"tryCatchPattern":"try {\n  const params = await readBoundedUrlEncodedForm(request, MAX_BYTES);\n} catch (err) {\n  if (err instanceof FormBodyError && err.status === 413) {\n    return new Response(`payload too large, limit ${MAX_BYTES} bytes`, { status: 413 });\n  }\n  throw err;\n}","preventionTips":["Enforce field length limits in the client before submit","Keep the route's maxBytes in sync with realistic input sizes","Log near-limit submissions to spot needed limit adjustments early"],"tags":["web","http","forms","limits"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}