{"record":{"id":"00eed0cfbdb60de6","repo":"Hmbown/CodeWhale","slug":"file-exceeds-size-limit","errorCode":null,"errorMessage":"file exceeds size limit","messagePattern":"file exceeds size limit","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"web/scripts/facts-publish.mjs","lineNumber":356,"sourceCode":"  return { positional, flags };\n}\n\n/** Bounded, regular, single-link file reads; no symlink or FIFO following. */\nexport function readBoundedFile(path, maxBytes = MAX_ENVELOPE_BYTES) {\n  const before = lstatSync(path);\n  if (!before.isFile() || before.nlink !== 1) throw new Error(\"file is not a regular single-link file\");\n  const fd = openSync(path, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0) | (constants.O_NONBLOCK ?? 0));\n  try {\n    const stat = fstatSync(fd);\n    if (!stat.isFile() || stat.nlink !== 1 || stat.size > maxBytes || stat.ino !== before.ino || stat.dev !== before.dev) throw new Error(\"file is not a bounded regular single-link file\");\n    const bytes = Buffer.alloc(maxBytes + 1);\n    let size = 0;\n    while (size <= maxBytes) {\n      const count = readSync(fd, bytes, size, maxBytes + 1 - size, null);\n      if (!count) break;\n      size += count;\n    }\n    if (size > maxBytes) throw new Error(\"file exceeds size limit\");\n    return bytes.subarray(0, size);\n  } finally { closeSync(fd); }\n}\n\nfunction loadPrivateKeyFromEnv() {\n  refuseUnderCi();\n  let pem = process.env.CODEWHALE_FACTS_SIGNING_KEY;\n  const file = process.env.CODEWHALE_FACTS_SIGNING_KEY_FILE;\n  if (!pem && file) pem = readBoundedFile(file, 16 * 1024).toString(\"utf8\");\n  if (!pem) throw new Error(\"set CODEWHALE_FACTS_SIGNING_KEY (PEM) or CODEWHALE_FACTS_SIGNING_KEY_FILE\");\n  if (Buffer.byteLength(pem) > 16 * 1024) throw new Error(\"signing key exceeds size limit\");\n  const key = createPrivateKey({ key: pem, format: \"pem\" });\n  if (key.asymmetricKeyType !== \"ed25519\") throw new Error(\"signing key must be Ed25519\");\n  return key;\n}\n\nexport function validateTrustedKeys(keys) {\n  const seen = new Set();","sourceCodeStart":338,"sourceCodeEnd":374,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/web/scripts/facts-publish.mjs#L338-L374","documentation":"readBoundedFile reads at most maxBytes+1 bytes and throws this error if it actually accumulated more than maxBytes, meaning the file grew past the bound during the read even though the pre-read stat looked acceptable. It is the final size gate for bounded reads.","triggerScenarios":"readBoundedFile(path, maxBytes) where the read loop collected size > maxBytes — the file exceeded the size cap (default MAX_ENVELOPE_BYTES, or 16 KiB when reading the signing key file).","commonSituations":"Pointing CODEWHALE_FACTS_SIGNING_KEY_FILE at a full keychain or concatenated PEM bundle larger than 16 KiB; the file being appended to between stat and read; wrong file passed (e.g. a bundle instead of a single key).","solutions":["Check the file size (`wc -c`) and confirm it fits the limit","Pass exactly one PEM key in the file, not a bundle","Use the CODEWHALE_FACTS_SIGNING_KEY env var with the PEM contents instead of a file","Extract the single key you need into a fresh small file"],"exampleFix":"// before\nCODEWHALE_FACTS_SIGNING_KEY_FILE=./all-keys.pem  # 40 KiB bundle\n// after\ngrep -B1 -A4 'BEGIN PRIVATE KEY' all-keys.pem | head -6 > key.pem\nCODEWHALE_FACTS_SIGNING_KEY_FILE=./key.pem","handlingStrategy":"validation","validationCode":"const st = statSync(path);\nif (st.size > MAX_ENVELOPE_BYTES) throw new Error(`${path} is ${st.size}B, limit is ${MAX_ENVELOPE_BYTES}B`);","typeGuard":"const fitsSizeLimit = (path, max = MAX_ENVELOPE_BYTES) => { try { return statSync(path).size <= max; } catch { return false; } };","tryCatchPattern":"try { bytes = readBoundedFile(file, 16 * 1024); } catch (e) { if (e.message === 'file exceeds size limit') { console.error(`${file} too large — provide a single PEM key under the limit`); process.exit(2); } throw e; }","preventionTips":["Keep one PEM key per file, no bundles","Run `wc -c` on key files before wiring them into env config","Prefer the env-var route with a single extracted key","Audit any template/secrets expansion that could concatenate keys"],"tags":["filesystem","size-limit"],"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-23T08:17:48.524Z"}