Hmbown/CodeWhale · error · Error

response exceeds size limit or has invalid length

Error message

response exceeds size limit or has invalid length

What it means

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.

Solutions

  1. Check the actual Content-Length of the response (curl -I) to see whether it is genuinely too large or malformed
  2. Fix the query filters so the response only returns needed rows (scope=eq.global&slug=eq.<channel>&select=id)
  3. Raise MAX_ENVELOPE_BYTES if legitimate envelopes have grown past the limit
  4. Inspect intermediate proxies/CDNs that may rewrite Content-Length headers
Defensive patterns

Strategy: validation

Validate before calling

const res = await fetch(url, { method: 'HEAD' });
const len = res.headers.get('content-length');
if (len !== null && (!/^\d+$/.test(len) || Number(len) > MAX_BYTES)) throw new Error('response too large before fetch');

Try / catch

try {
  const data = await readBoundedResponse(res);
} catch (e) {
  if (e.message.includes('size limit or invalid length')) console.error('Response Content-Length exceeded cap or is malformed; narrow the query');
  throw e;
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Understand the failure class

Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/1e5e654f8b63bc3e. Report an issue: GitHub.

Appendix: source

Thrown at web/scripts/facts-publish.mjs:475

    redirect: "error",
    headers: {
      apikey: key,
      Authorization: `Bearer ${key}`,
      "Content-Type": "application/json",
      ...(prefer ? { Prefer: prefer } : {}),
    },
    body: body === undefined ? undefined : JSON.stringify(body),
  });
  if (!res.ok) { await res.body?.cancel(); throw new Error(`PostgREST request failed (HTTP ${res.status})`); }
  const text = await readBoundedResponse(res);
  return text ? JSON.parse(text) : null;
}

export async function readBoundedResponse(response, maxBytes = MAX_ENVELOPE_BYTES) {
  const length = response.headers.get("content-length");
  if (length !== null && (!/^\d+$/.test(length) || Number(length) > maxBytes)) {
    await response.body?.cancel();
    throw new Error("response exceeds size limit or has invalid length");
  }
  if (!response.body) return "";
  const reader = response.body.getReader();
  const chunks = [];
  let size = 0;
  try {
    while (true) {
      const { value, done } = await reader.read();
      if (done) break;
      size += value.byteLength;
      if (size > maxBytes) throw new Error("response exceeds size limit");
      chunks.push(value);
    }
  } catch (error) { try { await reader.cancel(); } catch { /* Keep rejection. */ } throw error; }
  finally { reader.releaseLock(); }
  return new TextDecoder("utf-8", { fatal: true }).decode(Buffer.concat(chunks, size));
}

View on GitHub (pinned to 433685b202)