{"record":{"id":"fee2968eecefcfaa","repo":"Egonex-AI/Understand-Anything","slug":"symbol-baseline-file-inventory-does-not-match-the","errorCode":null,"errorMessage":"Symbol baseline file inventory does not match the incremental plan","messagePattern":"Symbol baseline file inventory does not match the incremental plan","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"understand-anything-plugin/skills/understand/validate-incremental-symbols.mjs","lineNumber":301,"sourceCode":"  };\n}\n\nexport function git(root, args) {\n  const result = spawnSync('git', args, { cwd: root, encoding: 'utf8', maxBuffer: 256 * 1024 * 1024 });\n  if (result.status !== 0) throw new Error(`git ${args[0]} failed: ${result.stderr || result.error || result.status}`);\n  return result.stdout;\n}\n\nexport function loadSymbolContext(projectRoot, intermediateDir) {\n  const plan = readJson(join(intermediateDir, 'incremental-plan.json'));\n  const baseline = readJson(join(intermediateDir, 'incremental-symbol-baseline.json'));\n  if (baseline.version !== 1 || baseline.baseCommit !== plan.baseCommit || baseline.headCommit !== plan.headCommit\n    || !Array.isArray(baseline.files)) throw new Error('Symbol baseline does not match the incremental plan');\n  const paths = baseline.files.map(file => file.filePath).sort();\n  if (JSON.stringify(paths) !== JSON.stringify([...plan.filesToReanalyze].sort())\n    || paths.some(path => !normalizePath(path) || (plan.deletedFiles ?? []).includes(path))\n    || new Set(paths).size !== paths.length) {\n    throw new Error('Symbol baseline file inventory does not match the incremental plan');\n  }\n  if (git(projectRoot, ['rev-parse', 'HEAD']).trim() !== plan.headCommit) {\n    throw new Error('HEAD changed since prepare; baseline not advanced');\n  }\n  // Check every analyzer input, even if all IDs survive and parsing is skipped.\n  // Git compares normalized contents, including repository clean/EOL rules.\n  if (paths.length) git(projectRoot, [\n    'diff', '--quiet', '--no-ext-diff', plan.headCommit, '--', ...paths.map(path => `:(literal)${path}`),\n  ]);\n  return { plan, baseline };\n}\n\nexport async function validateIncrementalSymbols(projectRoot, { graph, intermediateDir } = {}) {\n  const core = await getCore();\n  intermediateDir ??= join(core.resolveUaDir(projectRoot), 'intermediate');\n  const reportPath = join(intermediateDir, 'incremental-symbol-report.json');\n  const report = { version: 1, ok: false, files: [], unresolvedFiles: [], errors: [] };\n  const graphFromDisk = graph === undefined;","sourceCodeStart":283,"sourceCodeEnd":319,"githubUrl":"https://github.com/Egonex-AI/Understand-Anything/blob/07edf82a04371b6f69779b067bdc8a1a8753a9db/understand-anything-plugin/skills/understand/validate-incremental-symbols.mjs#L283-L319","documentation":"After the version/commit checks pass, `loadSymbolContext` cross-checks the baseline's file inventory against the plan: the sorted list of `baseline.files[].filePath` must exactly equal the plan's `filesToReanalyze`, every path must normalize non-empty, no path may appear in `plan.deletedFiles`, and there must be no duplicates. Any deviation throws this error, since symbol validation is only sound when both files agree on exactly which files to re-analyze.","triggerScenarios":"Calling `loadSymbolContext` when `filesToReanalyze` and the baseline file list differ (missing/extra files), a baseline entry has an empty/invalid `filePath`, a planned file also appears in `deletedFiles`, or the baseline contains the same filePath twice.","commonSituations":"Someone edited `incremental-plan.json` to add/remove a file after the baseline was built; a merge of two intermediate directories produced duplicate entries; renamed files appear both in filesToReanalyze and deletedFiles; a path with Windows separators failed normalizePath.","solutions":["Regenerate the plan and baseline together by re-running the incremental prepare step; do not edit either file by hand.","Diff `plan.filesToReanalyze` against `baseline.files[].filePath` to find the extra/missing entry and fix the prepare logic that produced it.","Remove duplicate filePath entries from the baseline (or fix the dedupe in the generator).","Ensure deleted files are excluded from filesToReanalyze and listed only in plan.deletedFiles.","Verify file paths are stored in normalized (POSIX-style) form."],"exampleFix":"// before: plan edited after baseline was written\nplan.filesToReanalyze: [\"src/a.ts\", \"src/b.ts\"]\nbaseline.files: [{ filePath: \"src/a.ts\" }]\n\n// after: regenerate baseline from the edited plan (or revert the plan edit)\n# re-run prepare so baseline.files matches filesToReanalyze exactly","handlingStrategy":"validation","validationCode":"const planPaths = [...plan.filesToReanalyze].sort();\nconst basePath = baseline.files.map(f => f.filePath).sort();\nconst inventoryOk = JSON.stringify(planPaths) === JSON.stringify(basePath)\n  && new Set(basePath).size === basePath.length\n  && basePath.every(p => typeof p === 'string' && p.length > 0)\n  && !basePath.some(p => (plan.deletedFiles ?? []).includes(p));\nif (!inventoryOk) rerunPrepareStep();","typeGuard":"function inventoriesMatch(plan, baseline) {\n  const paths = baseline.files.map(f => f?.filePath).sort();\n  return JSON.stringify(paths) === JSON.stringify([...plan.filesToReanalyze].sort())\n    && new Set(paths).size === paths.length\n    && paths.every(p => typeof p === 'string' && p.length > 0);\n}","tryCatchPattern":"try {\n  await validateIncrementalSymbols({ projectRoot, intermediateDir });\n} catch (err) {\n  if (err.message.includes('file inventory does not match')) {\n    console.error('Plan/baseline inventory drift; regenerating artifacts');\n    await rerunPrepareStep();\n  } else throw err;\n}","preventionTips":["Treat intermediate JSON files as build artifacts — regenerate, never hand-edit.","Keep filesToReanalyze and deletedFiles disjoint in the prepare logic.","Dedupe file paths when building the baseline.","Store paths in normalized POSIX form consistently."],"tags":["state-mismatch","incremental-analysis","validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"07edf82a04371b6f69779b067bdc8a1a8753a9db","analyzedAt":"2026-09-07T23:20:10.829Z","contentChangedAt":"2026-09-07T23:20:10.829Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}