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
- Diff the retry file list (incremental-symbol-retry-files.json) against the produced batches JSON to find which paths are missing or extra.
- Delete the stale incremental-symbol-retry-batches.json and re-run the script so batching recomputes.
- Check compute-batches.mjs's ignore/filter logic for rules that drop requested files; align it with the retry path list.
- 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
- Delete stale incremental-symbol-retry-batches.json before re-running retries.
- Keep prepare-symbol-retry.mjs and compute-batches.mjs at the same plugin version.
- Normalize paths identically (relative to projectRoot) on both sides of the comparison.
- Add a unit test asserting batch coverage equals the requested file set.
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
- Retry batching failed: ${batching.error ?? batching.status}
- Invalid retry batch index
- Batch artifact does not match the required shape
- Symbol retry requires a partial or architecture incremental
- Symbol retry already used for these commits; stop without ad
AI-assisted analysis of Egonex-AI/Understand-Anything@07edf82a04 (2026-09-07).
Data as JSON: /api/errors/e4c44646f4e35781.
Report an issue: GitHub.