Egonex-AI/Understand-Anything · error

Retry batches do not cover exactly the affected files

Error message

Retry batches do not cover exactly the affected files

What it means

After batching, the script asserts that the set of file paths scheduled across all returned batches is exactly equal (as sorted JSON arrays) to the set of unresolved retry paths. Any mismatch — missing files, extra files, or duplicates — means batching did not round-trip correctly, so it throws to prevent a partial retry from being recorded.

Source

Thrown at understand-anything-plugin/skills/understand/prepare-symbol-retry.mjs:51

  const report = await validateIncrementalSymbols(projectRoot, { intermediateDir });
  if (report.ok || report.unresolvedFiles.length === 0) {
    throw new Error('No unresolved symbol files eligible for a targeted retry; inspect the symbol report');
  }
  const paths = new Set(report.unresolvedFiles);
  const changedFilesPath = join(intermediateDir, 'incremental-symbol-retry-files.json');
  const batchesPath = join(intermediateDir, 'incremental-symbol-retry-batches.json');
  atomicWriteJson(changedFilesPath, [...paths]);
  const skillDir = dirname(fileURLToPath(import.meta.url));
  const batching = spawnSync(process.execPath, [
    join(skillDir, 'compute-batches.mjs'), projectRoot,
    `--changed-files=${changedFilesPath}`, `--output=${batchesPath}`,
  ], { encoding: 'utf8', maxBuffer: 64 * 1024 * 1024 });
  if (batching.stderr) process.stderr.write(batching.stderr);
  if (batching.status !== 0) throw new Error(`Retry batching failed: ${batching.error ?? batching.status}`);
  const batches = readJson(batchesPath).batches;
  const scheduled = batches.flatMap(batch => batch.files.map(file => file.path));
  if (JSON.stringify([...scheduled].sort()) !== JSON.stringify([...paths].sort())) {
    throw new Error('Retry batches do not cover exactly the affected files');
  }
  for (const batch of batches) {
    if (!Number.isInteger(batch.batchIndex) || batch.batchIndex < 1) throw new Error('Invalid retry batch index');
    const files = new Set(batch.files.map(file => file.path));
    batch.previousSymbols = baseline.files.filter(file => files.has(file.filePath)).flatMap(file =>
      file.nodes.filter(symbolKind).map(node => {
        const parents = new Set(file.edges.filter(edge => edge.type === 'contains' && edge.target === node.id)
          .map(edge => edge.source));
        const owners = file.nodes.filter(parent => parent.type === 'class' && parents.has(parent.id))
          .map(parent => parent.name);
        return {
          id: node.id, name: node.name, type: node.type, filePath: node.filePath,
          ...(node.lineRange ? { lineRange: node.lineRange } : {}),
          ...(owners.length ? { owners } : {}),
        };
      }),
    );
    batch.missingSymbols = report.files.filter(file => files.has(file.filePath));

View on GitHub (pinned to 07edf82a04)

Solutions

  1. Diff the retry file list (incremental-symbol-retry-files.json) against the produced batches JSON to find which paths are missing or extra.
  2. Delete the stale incremental-symbol-retry-batches.json and re-run the script so batching recomputes.
  3. Check compute-batches.mjs's ignore/filter logic for rules that drop requested files; align it with the retry path list.
  4. Ensure both sides normalize paths identically (relative to projectRoot) before comparing.

Example fix

// before: batching dropped an ignored file
scheduled = [a.js, b.js]; paths = [a.js, b.js, c.ts] → throw
// after: whitelist retry files in compute-batches ignore config, or re-run
delete .ua/intermediate/incremental-symbol-retry-batches.json
node prepare-symbol-retry.mjs .
Defensive patterns

Strategy: validation

Validate before calling

const requested = new Set(retryPaths);
const scheduled = new Set(batches.flatMap(b => b.files.map(f => f.path)));
const missing = [...requested].filter(p => !scheduled.has(p));
const extra = [...scheduled].filter(p => !requested.has(p));
if (missing.length || extra.length) {
  throw new Error(`Batch coverage mismatch; missing=${missing} extra=${extra}`);
}

Type guard

const coversExactly = (batches, paths) => {
  const s = new Set(batches.flatMap(b => b.files.map(f => f.path)));
  return s.size === paths.length && paths.every(p => s.has(p));
};

Try / catch

try {
  await runRetry(projectRoot);
} catch (e) {
  if (e.message.includes('Retry batches do not cover exactly')) {
    // delete stale batches output and re-run so batching recomputes
  } else throw e;
}

Prevention

When it happens

Trigger: compute-batches.mjs returns batches that drop some changed files, include files not requested, or duplicate a path — typically due to a batching bug, ignore-filter divergence inside compute-batches, or a stale/corrupt batches output JSON.

Common situations: compute-batches silently filtered files through its own ignore rules; a version mismatch between the prepare script and compute-batches.mjs; manually edited batches output from a previous run; paths normalized differently (relative vs absolute) on one side.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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