{"record":{"id":"af1468ead32ad458","repo":"Egonex-AI/Understand-Anything","slug":"invalid-retry-batch-index","errorCode":null,"errorMessage":"Invalid retry batch index","messagePattern":"Invalid retry batch index","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"understand-anything-plugin/skills/understand/prepare-symbol-retry.mjs","lineNumber":54,"sourceCode":"  }\n  const paths = new Set(report.unresolvedFiles);\n  const changedFilesPath = join(intermediateDir, 'incremental-symbol-retry-files.json');\n  const batchesPath = join(intermediateDir, 'incremental-symbol-retry-batches.json');\n  atomicWriteJson(changedFilesPath, [...paths]);\n  const skillDir = dirname(fileURLToPath(import.meta.url));\n  const batching = spawnSync(process.execPath, [\n    join(skillDir, 'compute-batches.mjs'), projectRoot,\n    `--changed-files=${changedFilesPath}`, `--output=${batchesPath}`,\n  ], { encoding: 'utf8', maxBuffer: 64 * 1024 * 1024 });\n  if (batching.stderr) process.stderr.write(batching.stderr);\n  if (batching.status !== 0) throw new Error(`Retry batching failed: ${batching.error ?? batching.status}`);\n  const batches = readJson(batchesPath).batches;\n  const scheduled = batches.flatMap(batch => batch.files.map(file => file.path));\n  if (JSON.stringify([...scheduled].sort()) !== JSON.stringify([...paths].sort())) {\n    throw new Error('Retry batches do not cover exactly the affected files');\n  }\n  for (const batch of batches) {\n    if (!Number.isInteger(batch.batchIndex) || batch.batchIndex < 1) throw new Error('Invalid retry batch index');\n    const files = new Set(batch.files.map(file => file.path));\n    batch.previousSymbols = baseline.files.filter(file => files.has(file.filePath)).flatMap(file =>\n      file.nodes.filter(symbolKind).map(node => {\n        const parents = new Set(file.edges.filter(edge => edge.type === 'contains' && edge.target === node.id)\n          .map(edge => edge.source));\n        const owners = file.nodes.filter(parent => parent.type === 'class' && parents.has(parent.id))\n          .map(parent => parent.name);\n        return {\n          id: node.id, name: node.name, type: node.type, filePath: node.filePath,\n          ...(node.lineRange ? { lineRange: node.lineRange } : {}),\n          ...(owners.length ? { owners } : {}),\n        };\n      }),\n    );\n    batch.missingSymbols = report.files.filter(file => files.has(file.filePath));\n  }\n  const assembled = readJson(join(intermediateDir, 'assembled-graph.json'));\n  const candidates = readJson(join(intermediateDir, 'incremental-edge-candidates.json'));","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/Egonex-AI/Understand-Anything/blob/07edf82a04371b6f69779b067bdc8a1a8753a9db/understand-anything-plugin/skills/understand/prepare-symbol-retry.mjs#L36-L72","documentation":"While annotating each retry batch with previous symbols, the script validates that batch.batchIndex is an integer >= 1. A missing, non-integer, zero, or negative batchIndex indicates a malformed batches file, so it throws before any batches are scheduled for execution.","triggerScenarios":"compute-batches.mjs produced (or a stale file contains) batch objects lacking a valid batchIndex — schema drift between batching versions, hand-edited JSON, or a partially written batches output.","commonSituations":"Older compute-batches.mjs version that emitted 0-based indices or omitted batchIndex; a corrupted/truncated batches JSON after a crash during atomic write (unlikely) or manual editing; test fixtures copied into the intermediate directory.","solutions":["Delete incremental-symbol-retry-batches.json and re-run prepare-symbol-retry.mjs so a fresh, current-version batches file is generated.","Verify the installed compute-batches.mjs matches the plugin version (no mixed old/new files in the skill directory).","Inspect the batches JSON to confirm each batch has an integer batchIndex >= 1; fix the generator if it emits 0-based indices."],"exampleFix":"// before: 0-based index from old batching\n{\"batchIndex\": 0, \"files\": [...]} → Error: Invalid retry batch index\n// after: regenerate with current script\nrm .ua/intermediate/incremental-symbol-retry-batches.json\nnode prepare-symbol-retry.mjs .  // batches now use 1-based indices","handlingStrategy":"validation","validationCode":"function assertValidBatches(batches) {\n  batches.forEach((b, i) => {\n    if (!Number.isInteger(b.batchIndex) || b.batchIndex < 1) {\n      throw new Error(`Batch ${i} has invalid batchIndex: ${b.batchIndex}`);\n    }\n  });\n}","typeGuard":"const hasValidBatchIndex = (batch) =>\n  typeof batch.batchIndex === 'number' && Number.isInteger(batch.batchIndex) && batch.batchIndex >= 1;","tryCatchPattern":"try {\n  await runRetry(projectRoot);\n} catch (e) {\n  if (e.message === 'Invalid retry batch index') {\n    // regenerate the batches file with the current compute-batches.mjs\n  } else throw e;\n}","preventionTips":["Regenerate the batches file rather than reusing old intermediate output.","Keep compute-batches.mjs and prepare-symbol-retry.mjs versions in sync (1-based indices).","Validate batches JSON against an expected schema before scheduling."],"tags":["batching","schema-validation","retry"],"backgroundTag":"schema-validation-failed","analyzedSha":"07edf82a04371b6f69779b067bdc8a1a8753a9db","analyzedAt":"2026-09-07T23:20:10.829Z","contentChangedAt":"2026-09-07T23:20:10.829Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}