vercel-labs/agent-skills · error · Error
codebase.json must be scan-codebase output with stack, route
Error message
codebase.json must be scan-codebase output with stack, routes[], and findings[].
What it means
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.
Source
Thrown at skills/vercel-optimize/scripts/merge-signals.mjs:45
const merged = mergeSignals(signals, codebase);
const body = JSON.stringify(merged, null, 2) + '\n';
if (args.outPath) {
await writeOutput(args.outPath, body, { force: args.force });
log(`wrote ${args.outPath}`);
} else {
process.stdout.write(body);
}
}
export function mergeSignals(signals, codebase) {
assertObject(signals, 'signals');
assertObject(codebase, 'codebase scan');
if (!signals.schemaVersion) {
throw new Error('signals.json is missing schemaVersion; pass collect-signals output as the first file.');
}
if (!Array.isArray(codebase.routes) || !Array.isArray(codebase.findings) || !codebase.stack) {
throw new Error('codebase.json must be scan-codebase output with stack, routes[], and findings[].');
}
return {
...signals,
codebase: annotateCodebaseScan(signals, codebase),
};
}
export function annotateCodebaseScan(signals, codebase) {
const index = buildRouteMetricIndex(signals);
return {
...codebase,
findings: (codebase.findings ?? []).map((finding) => annotateFinding(finding, index)),
};
}
function annotateFinding(finding, index) {
if (!finding || typeof finding !== 'object') return finding;View on GitHub (pinned to b8caa260a4)
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.
Example fix
# before — second file is not scan-codebase output $ node scripts/merge-signals.mjs signals.json partial.json -> codebase.json must be scan-codebase output with stack, routes[], and findings[]. # after — regenerate and merge the complete scan $ node scripts/scan-codebase.mjs . > codebase.json $ node scripts/merge-signals.mjs signals.json codebase.json -o merged.json
Defensive patterns
Strategy: type-guard
Validate before calling
import { readFileSync } from 'node:fs';
function loadCodebase(path) {
const c = JSON.parse(readFileSync(path, 'utf-8'));
if (!Array.isArray(c.routes) || !Array.isArray(c.findings) || !c.stack) {
throw new Error(`${path} is not scan-codebase output (needs stack, routes[], findings[])`);
}
return c;
}
const codebase = loadCodebase(process.argv[3]); Type guard
function isScanCodebaseOutput(v) {
return v !== null && typeof v === 'object' && !Array.isArray(v)
&& !!v.stack && Array.isArray(v.routes) && Array.isArray(v.findings);
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- signals.json is missing schemaVersion; pass collect-signals
- ${label} must be a JSON object.
- UNKNOWN_ARG
- VERCEL_NOT_INSTALLED
- VERCEL_VERSION_UNPARSEABLE
AI-assisted analysis of vercel-labs/agent-skills@b8caa260a4 (2026-08-13).
Data as JSON: /api/errors/89d1e36a8c25d37e.
Report an issue: GitHub.