{"record":{"id":"35e201c6a1291283","repo":"Egonex-AI/Understand-Anything","slug":"symbol-retry-already-used-for-these-commits-stop","errorCode":null,"errorMessage":"Symbol retry already used for these commits; stop without advancing the baseline","messagePattern":"Symbol retry already used for these commits; stop without advancing the baseline","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"understand-anything-plugin/skills/understand/prepare-symbol-retry.mjs","lineNumber":29,"sourceCode":"  normalizePath,\n  readJson,\n  symbolKind,\n  validateIncrementalSymbols,\n} from './validate-incremental-symbols.mjs';\n\nasync function main() {\n  if (process.argv.length !== 3) throw new Error('Usage: node prepare-symbol-retry.mjs <projectRoot>');\n  const projectRoot = realpathSync(process.argv[2]);\n  const intermediateDir = await getIntermediateDir(projectRoot);\n  const { plan, baseline } = loadSymbolContext(projectRoot, intermediateDir);\n  if (!['PARTIAL_UPDATE', 'ARCHITECTURE_UPDATE'].includes(plan.action)) {\n    throw new Error('Symbol retry requires a partial or architecture incremental update');\n  }\n  const retryPath = join(intermediateDir, 'incremental-symbol-retry.json');\n  if (existsSync(retryPath)) {\n    const retry = readJson(retryPath);\n    if (retry.baseCommit === plan.baseCommit && retry.headCommit === plan.headCommit && retry.attempt === 1) {\n      throw new Error('Symbol retry already used for these commits; stop without advancing the baseline');\n    }\n  }\n  // Do not trust an old report or a caller-supplied list of files to replace.\n  const report = await validateIncrementalSymbols(projectRoot, { intermediateDir });\n  if (report.ok || report.unresolvedFiles.length === 0) {\n    throw new Error('No unresolved symbol files eligible for a targeted retry; inspect the symbol report');\n  }\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}`);","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/Egonex-AI/Understand-Anything/blob/07edf82a04371b6f69779b067bdc8a1a8753a9db/understand-anything-plugin/skills/understand/prepare-symbol-retry.mjs#L11-L47","documentation":"The script enforces a one-shot retry policy: if a retry record exists for the same baseCommit and headCommit with attempt === 1, the retry has already been consumed and it throws, instructing the caller to stop without advancing the baseline. This prevents infinite retry loops against the same commit pair.","triggerScenarios":"Running prepare-symbol-retry.mjs a second time for the same base/head commit pair after a previous retry wrote incremental-symbol-retry.json with attempt 1.","commonSituations":"Re-running the retry script hoping a second attempt will help; CI retrying the script automatically; leftover retry record from a partially failed earlier run for the same commits.","solutions":["Stop retrying for these commits — the baseline must not advance via this path; run the normal incremental/full update instead.","Delete or move incremental-symbol-retry.json only if you are certain the previous retry never executed its batches (this is a deliberate operator decision).","Advance the commits (new HEAD) so the retry record no longer matches the current base/head pair."],"exampleFix":"// before: second attempt for same commits\nnode prepare-symbol-retry.mjs .\n// Error: Symbol retry already used for these commits; stop without advancing the baseline\n// after: perform the regular incremental update instead\nnode prepare-incremental.mjs .","handlingStrategy":"validation","validationCode":"import { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nconst retryPath = join(intermediateDir, 'incremental-symbol-retry.json');\nif (existsSync(retryPath)) {\n  const retry = JSON.parse(readFileSync(retryPath, 'utf-8'));\n  if (retry.attempt === 1 && retry.baseCommit === base && retry.headCommit === head) {\n    console.error('Retry already consumed for these commits; do not advance baseline.');\n    process.exit(1);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await runRetry(projectRoot);\n} catch (e) {\n  if (e.message.includes('Symbol retry already used')) {\n    // stop; run the normal incremental update instead of advancing baseline\n  } else throw e;\n}","preventionTips":["Track retry consumption in CI so the script is invoked at most once per commit pair.","Never delete incremental-symbol-retry.json as an automatic retry tactic.","Advance to a new HEAD before attempting another retry."],"tags":["retry","idempotency","one-shot","incremental-update"],"backgroundTag":"invalid-state-transition","analyzedSha":"07edf82a04371b6f69779b067bdc8a1a8753a9db","analyzedAt":"2026-09-07T23:20:10.829Z","contentChangedAt":"2026-09-07T23:20:10.829Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}