Egonex-AI/Understand-Anything · error · Error
Symbol baseline file inventory does not match the incrementa
Error message
Symbol baseline file inventory does not match the incremental plan
What it means
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.
Source
Thrown at understand-anything-plugin/skills/understand/validate-incremental-symbols.mjs:301
};
}
export function git(root, args) {
const result = spawnSync('git', args, { cwd: root, encoding: 'utf8', maxBuffer: 256 * 1024 * 1024 });
if (result.status !== 0) throw new Error(`git ${args[0]} failed: ${result.stderr || result.error || result.status}`);
return result.stdout;
}
export function loadSymbolContext(projectRoot, intermediateDir) {
const plan = readJson(join(intermediateDir, 'incremental-plan.json'));
const baseline = readJson(join(intermediateDir, 'incremental-symbol-baseline.json'));
if (baseline.version !== 1 || baseline.baseCommit !== plan.baseCommit || baseline.headCommit !== plan.headCommit
|| !Array.isArray(baseline.files)) throw new Error('Symbol baseline does not match the incremental plan');
const paths = baseline.files.map(file => file.filePath).sort();
if (JSON.stringify(paths) !== JSON.stringify([...plan.filesToReanalyze].sort())
|| paths.some(path => !normalizePath(path) || (plan.deletedFiles ?? []).includes(path))
|| new Set(paths).size !== paths.length) {
throw new Error('Symbol baseline file inventory does not match the incremental plan');
}
if (git(projectRoot, ['rev-parse', 'HEAD']).trim() !== plan.headCommit) {
throw new Error('HEAD changed since prepare; baseline not advanced');
}
// Check every analyzer input, even if all IDs survive and parsing is skipped.
// Git compares normalized contents, including repository clean/EOL rules.
if (paths.length) git(projectRoot, [
'diff', '--quiet', '--no-ext-diff', plan.headCommit, '--', ...paths.map(path => `:(literal)${path}`),
]);
return { plan, baseline };
}
export async function validateIncrementalSymbols(projectRoot, { graph, intermediateDir } = {}) {
const core = await getCore();
intermediateDir ??= join(core.resolveUaDir(projectRoot), 'intermediate');
const reportPath = join(intermediateDir, 'incremental-symbol-report.json');
const report = { version: 1, ok: false, files: [], unresolvedFiles: [], errors: [] };
const graphFromDisk = graph === undefined;View on GitHub (pinned to 07edf82a04)
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.
Example fix
// before: plan edited after baseline was written
plan.filesToReanalyze: ["src/a.ts", "src/b.ts"]
baseline.files: [{ filePath: "src/a.ts" }]
// after: regenerate baseline from the edited plan (or revert the plan edit)
# re-run prepare so baseline.files matches filesToReanalyze exactly Defensive patterns
Strategy: validation
Validate before calling
const planPaths = [...plan.filesToReanalyze].sort(); const basePath = baseline.files.map(f => f.filePath).sort(); const inventoryOk = JSON.stringify(planPaths) === JSON.stringify(basePath) && new Set(basePath).size === basePath.length && basePath.every(p => typeof p === 'string' && p.length > 0) && !basePath.some(p => (plan.deletedFiles ?? []).includes(p)); if (!inventoryOk) rerunPrepareStep();
Type guard
function inventoriesMatch(plan, baseline) {
const paths = baseline.files.map(f => f?.filePath).sort();
return JSON.stringify(paths) === JSON.stringify([...plan.filesToReanalyze].sort())
&& new Set(paths).size === paths.length
&& paths.every(p => typeof p === 'string' && p.length > 0);
} Try / catch
try {
await validateIncrementalSymbols({ projectRoot, intermediateDir });
} catch (err) {
if (err.message.includes('file inventory does not match')) {
console.error('Plan/baseline inventory drift; regenerating artifacts');
await rerunPrepareStep();
} else throw err;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Symbol baseline does not match the incremental plan
- Invalid knowledge graph: ${result.fatal ?? "unknown error"}
- Invalid domain graph: ${result.fatal ?? "unknown error"}
- Freshness response was malformed
- Scan artifact does not match the required shape
AI-assisted analysis of Egonex-AI/Understand-Anything@07edf82a04 (2026-09-07).
Data as JSON: /api/errors/fee2968eecefcfaa.
Report an issue: GitHub.