{"record":{"id":"89d1e36a8c25d37e","repo":"vercel-labs/agent-skills","slug":"codebase-json-must-be-scan-codebase-output-with-st","errorCode":null,"errorMessage":"codebase.json must be scan-codebase output with stack, routes[], and findings[].","messagePattern":"codebase\\.json must be scan-codebase output with stack, routes\\[\\], and findings\\[\\]\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"skills/vercel-optimize/scripts/merge-signals.mjs","lineNumber":45,"sourceCode":"  const merged = mergeSignals(signals, codebase);\n  const body = JSON.stringify(merged, null, 2) + '\\n';\n  if (args.outPath) {\n    await writeOutput(args.outPath, body, { force: args.force });\n    log(`wrote ${args.outPath}`);\n  } else {\n    process.stdout.write(body);\n  }\n}\n\nexport function mergeSignals(signals, codebase) {\n  assertObject(signals, 'signals');\n  assertObject(codebase, 'codebase scan');\n\n  if (!signals.schemaVersion) {\n    throw new Error('signals.json is missing schemaVersion; pass collect-signals output as the first file.');\n  }\n  if (!Array.isArray(codebase.routes) || !Array.isArray(codebase.findings) || !codebase.stack) {\n    throw new Error('codebase.json must be scan-codebase output with stack, routes[], and findings[].');\n  }\n\n  return {\n    ...signals,\n    codebase: annotateCodebaseScan(signals, codebase),\n  };\n}\n\nexport function annotateCodebaseScan(signals, codebase) {\n  const index = buildRouteMetricIndex(signals);\n  return {\n    ...codebase,\n    findings: (codebase.findings ?? []).map((finding) => annotateFinding(finding, index)),\n  };\n}\n\nfunction annotateFinding(finding, index) {\n  if (!finding || typeof finding !== 'object') return finding;","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/vercel-labs/agent-skills/blob/b8caa260a420a73042e35521de4b5c8baf6446cc/skills/vercel-optimize/scripts/merge-signals.mjs#L27-L63","documentation":"Thrown by mergeSignals() when the second `codebase` argument is not valid scan-codebase output — it must be an object with `routes` (array), `findings` (array), and a truthy `stack`. Any of these missing/falsy means the file is not from scan-codebase, and annotating it against signals would produce a malformed merged brief.","triggerScenarios":"Passing a codebase.json that is actually collect-signals output; a truncated/empty scan-codebase run; a hand-authored file missing routes/findings/stack; a codebase scan that errored out and wrote a partial object.","commonSituations":"Files swapped (codebase slot holds signals); scan-codebase failed silently and wrote `{}`; an old codebase.json from before routes/findings were added to the schema.","solutions":["Re-run scan-codebase to produce a complete codebase.json with stack, routes[], and findings[].","Verify the second positional is the scan-codebase file, not the signals file.","Inspect codebase.json and confirm all three fields are present and non-empty before merging."],"exampleFix":"# before — second file is not scan-codebase output\n$ node scripts/merge-signals.mjs signals.json partial.json\n-> codebase.json must be scan-codebase output with stack, routes[], and findings[].\n\n# after — regenerate and merge the complete scan\n$ node scripts/scan-codebase.mjs . > codebase.json\n$ node scripts/merge-signals.mjs signals.json codebase.json -o merged.json","handlingStrategy":"type-guard","validationCode":"import { readFileSync } from 'node:fs';\nfunction loadCodebase(path) {\n  const c = JSON.parse(readFileSync(path, 'utf-8'));\n  if (!Array.isArray(c.routes) || !Array.isArray(c.findings) || !c.stack) {\n    throw new Error(`${path} is not scan-codebase output (needs stack, routes[], findings[])`);\n  }\n  return c;\n}\nconst codebase = loadCodebase(process.argv[3]);","typeGuard":"function isScanCodebaseOutput(v) {\n  return v !== null && typeof v === 'object' && !Array.isArray(v)\n    && !!v.stack && Array.isArray(v.routes) && Array.isArray(v.findings);\n}","tryCatchPattern":null,"preventionTips":["Pass scan-codebase output as the second file to merge-signals.","Re-run scan-codebase if routes/findings/stack are missing.","Validate the codebase scan object shape before merging."],"tags":["validation","data-contract","arguments","vercel"],"backgroundTag":null,"analyzedSha":"b8caa260a420a73042e35521de4b5c8baf6446cc","analyzedAt":"2026-08-13T06:03:29.508Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}