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

  1. Delete the stale intermediate artifacts (`incremental-plan.json`, `incremental-symbol-baseline.json`) and re-run the prepare step to regenerate them together.
  2. Confirm both files come from the same run: their `baseCommit` and `headCommit` fields must be identical.
  3. Check the tool version that produced the baseline — regenerate it if your validator expects version 1.
  4. 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

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


AI-assisted analysis of Egonex-AI/Understand-Anything@07edf82a04 (2026-09-07). Data as JSON: /api/errors/03cf5014e388b118. Report an issue: GitHub.