Egonex-AI/Understand-Anything · error · Error
Symbol baseline does not match the incremental plan
Error message
Symbol baseline does not match the incremental plan
What it means
`loadSymbolContext` loads `incremental-plan.json` and `incremental-symbol-baseline.json` from the intermediate directory and verifies they describe the same incremental run: baseline schema version 1, matching baseCommit/headCommit, and a files array. If any check fails it throws this error, because validating symbols against a baseline from a different plan would produce incorrect results.
Source
Thrown at understand-anything-plugin/skills/understand/validate-incremental-symbols.mjs:296
afterCount: current.nodes.length,
beforeSymbolCount: oldSymbols.length,
afterSymbolCount: newSymbols.length,
missing,
replacements,
};
}
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 } = {}) {View on GitHub (pinned to 07edf82a04)
Solutions
- Delete the stale intermediate artifacts (`incremental-plan.json`, `incremental-symbol-baseline.json`) and re-run the prepare step to regenerate them together.
- Confirm both files come from the same run: their `baseCommit` and `headCommit` fields must be identical.
- Check the tool version that produced the baseline — regenerate it if your validator expects version 1.
- Ensure the whole `intermediate/` directory is cleaned between runs on different branches.
Example fix
// before: stale mixed artifacts
intermediate/incremental-plan.json { "baseCommit": "aaa", "headCommit": "bbb" }
intermediate/incremental-symbol-baseline.json { "baseCommit": "xxx", "headCommit": "yyy" }
// after: regenerate both from one prepare run
rm .ua/intermediate/incremental-plan.json .ua/intermediate/incremental-symbol-baseline.json
# re-run /understand prepare so both files are written from the same plan Defensive patterns
Strategy: validation
Validate before calling
const plan = JSON.parse(readFileSync(join(dir,'incremental-plan.json'),'utf8')); const baseline = JSON.parse(readFileSync(join(dir,'incremental-symbol-baseline.json'),'utf8')); const compatible = baseline.version === 1 && baseline.baseCommit === plan.baseCommit && baseline.headCommit === plan.headCommit && Array.isArray(baseline.files); if (!compatible) regeneratePlanAndBaseline();
Type guard
function isCompatibleBaseline(plan, baseline) {
return typeof baseline === 'object' && baseline !== null
&& baseline.version === 1
&& baseline.baseCommit === plan.baseCommit
&& baseline.headCommit === plan.headCommit
&& Array.isArray(baseline.files);
} Try / catch
try {
await validateIncrementalSymbols({ projectRoot, intermediateDir });
} catch (err) {
if (err.message === 'Symbol baseline does not match the incremental plan') {
await rerunPrepareStep(); // regenerate both artifacts together
} else throw err;
} Prevention
- Never edit incremental-plan.json or the baseline by hand.
- Regenerate plan and baseline in the same prepare run; clean intermediate/ between runs.
- Pin the validator and artifact-writer to the same schema version.
- Don't reuse intermediate artifacts across branches.
When it happens
Trigger: Calling `loadSymbolContext(projectRoot, intermediateDir)` when the baseline's `version` is not 1, its `baseCommit`/`headCommit` differ from the plan's, or `baseline.files` is not an array — typically stale or hand-edited intermediate files.
Common situations: A previous incremental run was interrupted halfway (plan written, baseline not); a newer tool version wrote an incompatible baseline; the intermediate directory mixes artifacts from two branches; files were edited manually or partially copied.
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 file inventory does not match the incrementa
- Invalid knowledge graph: ${result.fatal ?? "unknown error"}
- Invalid domain graph: ${result.fatal ?? "unknown error"}
- JSON changed-file list must be an array of strings
- Architecture update requires layers.json; baseline not advan
AI-assisted analysis of Egonex-AI/Understand-Anything@07edf82a04 (2026-09-07).
Data as JSON: /api/errors/03cf5014e388b118.
Report an issue: GitHub.