vercel-labs/agent-skills · error · Error
signals.json is missing schemaVersion; pass collect-signals
Error message
signals.json is missing schemaVersion; pass collect-signals output as the first file.
What it means
Thrown by mergeSignals() when the first `signals` argument has no `schemaVersion` field. collect-signals.mjs always emits a `schemaVersion` at the top of its output object, so its absence means the first file is not collect-signals output — typically the two input files were passed in the wrong order. The guard prevents merging a codebase scan as if it were metrics signals.
Source
Thrown at skills/vercel-optimize/scripts/merge-signals.mjs:42
readJson(args.codebasePath, 'codebase scan'),
]);
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)),
};
}View on GitHub (pinned to b8caa260a4)
Solutions
- Pass files in the correct order: `merge-signals.mjs <signals.json> <codebase.json>` — collect-signals output first.
- Re-run collect-signals to regenerate a complete signals.json that includes schemaVersion.
- If merging manually via mergeSignals(), ensure the first argument is the object from collect-signals.
Example fix
# before (wrong order) $ node scripts/merge-signals.mjs codebase.json signals.json -o merged.json -> signals.json is missing schemaVersion # after (correct order) $ 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 loadSignals(path) {
const s = JSON.parse(readFileSync(path, 'utf-8'));
if (!s.schemaVersion) throw new Error(`${path} is not collect-signals output (missing schemaVersion)`);
return s;
}
const signals = loadSignals(process.argv[2]); Type guard
function isCollectSignalsOutput(v) {
return v !== null && typeof v === 'object' && !Array.isArray(v) && typeof v.schemaVersion !== 'undefined';
} Prevention
- Always pass collect-signals output as the first file to merge-signals.
- Re-run collect-signals if the signals file predates the schemaVersion field.
- Smoke-check the signals file for schemaVersion before merging.
When it happens
Trigger: Calling merge-signals with codebase.json first and signals.json second; passing a hand-written or partial JSON that lacks schemaVersion; passing an older/different collector output that never had the field.
Common situations: Argument order swapped on the command line; a wrapper script feeding files in the wrong order; an out-of-date collect-signals run predating the schemaVersion field.
Related errors
- codebase.json must be scan-codebase output with stack, route
- ${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/1908da47abce70e7.
Report an issue: GitHub.