JuliusBrussee/caveman · error · Error
[extract-atlas] missing numeric const
Error message
[extract-atlas] missing numeric const ${name} What it means
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.
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)
Example fix
// before export const TILE_SIZE = 2 ** 4; // after export const TILE_SIZE = 16;
Defensive patterns
Strategy: validation
Validate before calling
function numericConstPresent(src, name) {
return new RegExp(`export\\s+const\\s+${name}\\s*=\\s*(\\d+)\\s*;`).test(src);
}
if (!numericConstPresent(src, "TILE_SIZE")) throw new Error("fix constant before running extract-atlas"); Try / catch
try {
runAtlasExtract();
} catch (e) {
if (String(e.message).includes("missing numeric const")) {
const name = e.message.split("missing numeric const ")[1];
console.error(`Add 'export const ${name} = <integer>;' back to the source`);
} else throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- [extract-atlas] missing base64 const
- [extract-atlas] = , want
- adapter-specific build_sha256 values must differ
- agent conformance fixtures must cover claude and pi
- agent conformance mismatch
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/d5f3ffd8edf3d581.
Report an issue: GitHub.
Appendix: source
Thrown at engine/pixel/internal/atlasgen/extract-atlas.mjs:30
console.error('usage: node public/engine/pixel/internal/atlasgen/extract-atlas.mjs <pxpipe-root>');
process.exit(2);
}
const pxpipeRoot = process.argv[2] ? resolve(process.argv[2]) : '';
if (!pxpipeRoot) usage();
const repoRoot = resolve(new URL('../../../../..', import.meta.url).pathname);
const outDir = join(repoRoot, 'public/engine/pixel/assets');
mkdirSync(outDir, { recursive: true });
function readSource(rel) {
return readFileSync(join(pxpipeRoot, rel), 'utf8');
}
function constNumber(src, name) {
const re = new RegExp(`export\\s+const\\s+${name}\\s*=\\s*(\\d+)\\s*;`);
const m = src.match(re);
if (!m) throw new Error(`[extract-atlas] missing numeric const ${name}`);
return Number(m[1]);
}
function constB64(src, name) {
const re = new RegExp(`const\\s+${name}\\s*=\\s*"([^"]+)"\\s*;`);
const m = src.match(re);
if (!m) throw new Error(`[extract-atlas] missing base64 const ${name}`);
return Buffer.from(m[1], 'base64');
}
function assertHeader(src, expected) {
for (const [name, want] of Object.entries(expected)) {
const got = constNumber(src, name);
if (got !== want) {
throw new Error(`[extract-atlas] ${name}=${got}, want ${want}`);
}
}
}View on GitHub (pinned to 3ee70a1026)