{"record":{"id":"1e5e654f8b63bc3e","repo":"Hmbown/CodeWhale","slug":"response-exceeds-size-limit-or-has-invalid-length","errorCode":null,"errorMessage":"response exceeds size limit or has invalid length","messagePattern":"response exceeds size limit or has invalid length","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"web/scripts/facts-publish.mjs","lineNumber":475,"sourceCode":"    redirect: \"error\",\n    headers: {\n      apikey: key,\n      Authorization: `Bearer ${key}`,\n      \"Content-Type\": \"application/json\",\n      ...(prefer ? { Prefer: prefer } : {}),\n    },\n    body: body === undefined ? undefined : JSON.stringify(body),\n  });\n  if (!res.ok) { await res.body?.cancel(); throw new Error(`PostgREST request failed (HTTP ${res.status})`); }\n  const text = await readBoundedResponse(res);\n  return text ? JSON.parse(text) : null;\n}\n\nexport async function readBoundedResponse(response, maxBytes = MAX_ENVELOPE_BYTES) {\n  const length = response.headers.get(\"content-length\");\n  if (length !== null && (!/^\\d+$/.test(length) || Number(length) > maxBytes)) {\n    await response.body?.cancel();\n    throw new Error(\"response exceeds size limit or has invalid length\");\n  }\n  if (!response.body) return \"\";\n  const reader = response.body.getReader();\n  const chunks = [];\n  let size = 0;\n  try {\n    while (true) {\n      const { value, done } = await reader.read();\n      if (done) break;\n      size += value.byteLength;\n      if (size > maxBytes) throw new Error(\"response exceeds size limit\");\n      chunks.push(value);\n    }\n  } catch (error) { try { await reader.cancel(); } catch { /* Keep rejection. */ } throw error; }\n  finally { reader.releaseLock(); }\n  return new TextDecoder(\"utf-8\", { fatal: true }).decode(Buffer.concat(chunks, size));\n}\n","sourceCodeStart":457,"sourceCodeEnd":493,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/web/scripts/facts-publish.mjs#L457-L493","documentation":"readBoundedResponse() guards against oversized or malformed responses. If the Content-Length header is present but is not a pure digit string, or exceeds the configured maxBytes (MAX_ENVELOPE_BYTES), it cancels the body and throws this error before reading anything. It exists so a compromised or misconfigured PostgREST endpoint cannot flood memory.","triggerScenarios":"A PostgREST GET (e.g. facts_channel select) returns a Content-Length header larger than MAX_ENVELOPE_BYTES, or a proxy injects a malformed Content-Length header (non-numeric).","commonSituations":"A channel/key query unexpectedly returning a huge result set because filters are wrong (scope/slug filters dropped, returning all rows); a corporate proxy or CDN adding a bogus Content-Length; maxBytes configured too small for the actual payload.","solutions":["Check the actual Content-Length of the response (curl -I) to see whether it is genuinely too large or malformed","Fix the query filters so the response only returns needed rows (scope=eq.global&slug=eq.<channel>&select=id)","Raise MAX_ENVELOPE_BYTES if legitimate envelopes have grown past the limit","Inspect intermediate proxies/CDNs that may rewrite Content-Length headers"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const res = await fetch(url, { method: 'HEAD' });\nconst len = res.headers.get('content-length');\nif (len !== null && (!/^\\d+$/.test(len) || Number(len) > MAX_BYTES)) throw new Error('response too large before fetch');","typeGuard":null,"tryCatchPattern":"try {\n  const data = await readBoundedResponse(res);\n} catch (e) {\n  if (e.message.includes('size limit or invalid length')) console.error('Response Content-Length exceeded cap or is malformed; narrow the query');\n  throw e;\n}","preventionTips":["Always add select= and eq. filters to PostgREST queries","Keep responses bounded with limit= when listing","Review MAX_ENVELOPE_BYTES when envelope formats change","Beware proxies that rewrite Content-Length"],"tags":["http","size-limit","validation"],"backgroundTag":"file-size-limit-exceeded","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}