{"record":{"id":"1908da47abce70e7","repo":"vercel-labs/agent-skills","slug":"signals-json-is-missing-schemaversion-pass-collec","errorCode":null,"errorMessage":"signals.json is missing schemaVersion; pass collect-signals output as the first file.","messagePattern":"signals\\.json is missing schemaVersion; pass collect-signals output as the first file\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"skills/vercel-optimize/scripts/merge-signals.mjs","lineNumber":42,"sourceCode":"    readJson(args.codebasePath, 'codebase scan'),\n  ]);\n\n  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}","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/vercel-labs/agent-skills/blob/b8caa260a420a73042e35521de4b5c8baf6446cc/skills/vercel-optimize/scripts/merge-signals.mjs#L24-L60","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before (wrong order)\n$ node scripts/merge-signals.mjs codebase.json signals.json -o merged.json\n-> signals.json is missing schemaVersion\n\n# after (correct order)\n$ node scripts/merge-signals.mjs signals.json codebase.json -o merged.json","handlingStrategy":"type-guard","validationCode":"import { readFileSync } from 'node:fs';\nfunction loadSignals(path) {\n  const s = JSON.parse(readFileSync(path, 'utf-8'));\n  if (!s.schemaVersion) throw new Error(`${path} is not collect-signals output (missing schemaVersion)`);\n  return s;\n}\nconst signals = loadSignals(process.argv[2]);","typeGuard":"function isCollectSignalsOutput(v) {\n  return v !== null && typeof v === 'object' && !Array.isArray(v) && typeof v.schemaVersion !== 'undefined';\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["arguments","validation","data-contract","vercel"],"backgroundTag":null,"analyzedSha":"b8caa260a420a73042e35521de4b5c8baf6446cc","analyzedAt":"2026-08-13T06:03:29.508Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}