{"record":{"id":"1cb3b7e5940a5bfb","repo":"JuliusBrussee/caveman","slug":"extract-atlas-missing-base64-const-name","errorCode":null,"errorMessage":"[extract-atlas] missing base64 const ${name}","messagePattern":"\\[extract-atlas\\] missing base64 const (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"engine/pixel/internal/atlasgen/extract-atlas.mjs","lineNumber":37,"sourceCode":"const 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}\n\nfunction writeBlob(name, bytes) {\n  const out = join(outDir, name);\n  writeFileSync(out, gzipSync(bytes, { level: 9 }));\n  console.log(`${basename(out)} raw=${bytes.length} gzip=${readFileSync(out).length}`);\n}\n","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/engine/pixel/internal/atlasgen/extract-atlas.mjs#L19-L55","documentation":"`constB64` extracts base64 string constants (`const NAME = \"...\";`) from source text read by extract-atlas.mjs and decodes them to a Buffer. This error is thrown when the regex finds no match, meaning the expected base64 constant is missing or no longer a plain double-quoted string literal.","triggerScenarios":"Source no longer contains `const ${name} = \"<base64>\";` — the constant was renamed, moved to another file, changed to a template literal/backticks, imported instead of declared, or split across lines.","commonSituations":"A formatter or minifier rewrote the string literal; the asset blob was moved into a separate .json/.bin file during a refactor; the constant was made `export const` with extra spacing that still matches but the value was emptied and replaced with dynamic generation.","solutions":["Restore the constant as a single-line double-quoted string: const NAME = \"<base64>\";","Re-run the step that generates the embedded blob so the constant is regenerated in place","If the data moved to a file, change extract-atlas.mjs to read the file instead of regexing source","Check that the correct source text (not an empty or wrong file's contents) is passed to constB64"],"exampleFix":"// before\nconst ATLAS_PNG = await loadAtlas(); // dynamic, regex can't match\n// after\nconst ATLAS_PNG = \"iVBORw0KGgo...\"; // plain base64 literal","handlingStrategy":"validation","validationCode":"function b64ConstPresent(src, name) {\n  return new RegExp(`const\\\\s+${name}\\\\s*=\\\\s*\"([^\"]+)\"\\\\s*;`).test(src);\n}\nif (!b64ConstPresent(src, \"ATLAS_PNG\")) throw new Error(\"base64 blob constant missing\");","typeGuard":null,"tryCatchPattern":"try {\n  runAtlasExtract();\n} catch (e) {\n  if (String(e.message).includes(\"missing base64 const\")) {\n    console.error(\"Regenerate the embedded base64 constant before extracting the atlas\");\n  } else throw e;\n}","preventionTips":["Keep base64 blobs as single-line double-quoted string literals","Run the blob generator before extract-atlas in the build order","Disable formatters/minifiers for files carrying generated string constants","Move large blobs to data files instead of inlining if constants keep churning"],"tags":["regex","base64","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"}