{"record":{"id":"d5f3ffd8edf3d581","repo":"JuliusBrussee/caveman","slug":"extract-atlas-missing-numeric-const-name","errorCode":null,"errorMessage":"[extract-atlas] missing numeric const ${name}","messagePattern":"\\[extract-atlas\\] missing numeric const (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"engine/pixel/internal/atlasgen/extract-atlas.mjs","lineNumber":30,"sourceCode":"  console.error('usage: node public/engine/pixel/internal/atlasgen/extract-atlas.mjs <pxpipe-root>');\n  process.exit(2);\n}\n\nconst pxpipeRoot = process.argv[2] ? resolve(process.argv[2]) : '';\nif (!pxpipeRoot) usage();\n\nconst repoRoot = resolve(new URL('../../../../..', import.meta.url).pathname);\nconst outDir = join(repoRoot, 'public/engine/pixel/assets');\nmkdirSync(outDir, { recursive: true });\n\nfunction readSource(rel) {\n  return readFileSync(join(pxpipeRoot, rel), 'utf8');\n}\n\nfunction constNumber(src, name) {\n  const re = new RegExp(`export\\\\s+const\\\\s+${name}\\\\s*=\\\\s*(\\\\d+)\\\\s*;`);\n  const m = src.match(re);\n  if (!m) throw new Error(`[extract-atlas] missing numeric const ${name}`);\n  return Number(m[1]);\n}\n\nfunction constB64(src, name) {\n  const re = new RegExp(`const\\\\s+${name}\\\\s*=\\\\s*\"([^\"]+)\"\\\\s*;`);\n  const m = src.match(re);\n  if (!m) throw new Error(`[extract-atlas] missing base64 const ${name}`);\n  return Buffer.from(m[1], 'base64');\n}\n\nfunction assertHeader(src, expected) {\n  for (const [name, want] of Object.entries(expected)) {\n    const got = constNumber(src, name);\n    if (got !== want) {\n      throw new Error(`[extract-atlas] ${name}=${got}, want ${want}`);\n    }\n  }\n}","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/engine/pixel/internal/atlasgen/extract-atlas.mjs#L12-L48","documentation":"The atlas generation script `extract-atlas.mjs` reads other source files as text and pulls out numeric `export const` declarations via regex (`constNumber`). This error is thrown when the regex `export const NAME = <digits>;` does not match, meaning a required numeric constant is absent or its form changed.","triggerScenarios":"Source file passed to constNumber no longer contains `export const ${name} = <integer>;` — constant renamed, converted to a computed/calculated value, changed to a float or string, or removed.","commonSituations":"A refactor changed `const TILE = 16;` to `const TILE = 2 ** 4;` or imported it from another module; someone added a type annotation or made the value non-integer; the wrong source file's text is passed in.","solutions":["Open the source file and restore the constant to plain `export const NAME = 12345;` form","If the constant was legitimately changed, keep the literal numeric form so the regex still matches","Update extract-atlas.mjs to read the new declaration form or parse the AST instead of regex","Confirm the correct file contents are being read (check the pxpipeRoot/rel path feeding constNumber)"],"exampleFix":"// before\nexport const TILE_SIZE = 2 ** 4;\n// after\nexport const TILE_SIZE = 16;","handlingStrategy":"validation","validationCode":"function numericConstPresent(src, name) {\n  return new RegExp(`export\\\\s+const\\\\s+${name}\\\\s*=\\\\s*(\\\\d+)\\\\s*;`).test(src);\n}\nif (!numericConstPresent(src, \"TILE_SIZE\")) throw new Error(\"fix constant before running extract-atlas\");","typeGuard":null,"tryCatchPattern":"try {\n  runAtlasExtract();\n} catch (e) {\n  if (String(e.message).includes(\"missing numeric const\")) {\n    const name = e.message.split(\"missing numeric const \")[1];\n    console.error(`Add 'export const ${name} = <integer>;' back to the source`);\n  } else throw e;\n}","preventionTips":["Keep required constants as plain integer literals in the expected file","Avoid renaming or moving constants consumed by the atlas generator","Regenerate the pipeline files rather than hand-editing their declarations","Prefer parsing (AST) over regex if declarations must evolve"],"tags":["regex","build","atlas"],"backgroundTag":"missing-config-key","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}