{"record":{"id":"600e8d5d67558ec0","repo":"abhigyanpatwari/GitNexus","slug":"worker-workerindex-parse-job-idle-timeout-exhau","errorCode":null,"errorMessage":"Worker ${workerIndex} parse job idle timeout exhausted retries; quarantining file and respawning slot.","messagePattern":"Worker (.+?) parse job idle timeout exhausted retries; quarantining file and respawning slot\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gitnexus/src/core/ingestion/workers/worker-pool.ts","lineNumber":1941,"sourceCode":"              timeoutSec: job.timeoutMs / 1000,\n              attempt: nextAttempt,\n              maxAttempts: poolOptions.maxTimeoutRetries + 1,\n              nextTimeoutSec: nextTimeout / 1000,\n            },\n            `Worker ${workerIndex} parse job idle timeout (single item). Retrying with ${nextTimeout / 1000}s timeout.`,\n          );\n          jobs.unshift({\n            ...job,\n            attempt: nextAttempt,\n            timeoutMs: nextTimeout,\n            cumulativeTimeoutMs: nextCumulative,\n          });\n          return { kind: 'retry' };\n        }\n\n        const stalledPath = inFlightPath ?? itemPath(job.items[0]);\n        const excludes = stalledPath ? [stalledPath] : [];\n        logger.warn(\n          {\n            workerIndex,\n            timeoutSec: job.timeoutMs / 1000,\n            stalledPath,\n            cumulativeMs: job.cumulativeTimeoutMs,\n          },\n          `Worker ${workerIndex} parse job idle timeout exhausted retries; quarantining file and respawning slot.`,\n        );\n        return {\n          kind: 'give-up',\n          reason:\n            `Worker ${workerIndex} parse job idle timeout after ${job.timeoutMs / 1000}s ` +\n            `(single item${stalledPath ? `: ${stalledPath}` : ''}, ` +\n            `${job.estimatedBytes} bytes, last progress: ${lastProgress})`,\n          excludePaths: excludes,\n        };\n      };\n","sourceCodeStart":1923,"sourceCodeEnd":1959,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/0d1aed942f0e8b5d3bac27519fff441aceea722d/gitnexus/src/core/ingestion/workers/worker-pool.ts#L1923-L1959","documentation":"Terminal timeout path: a single-item job exhausted maxTimeoutRetries. The pool computes the stalled path (in-flight file, else items[0]), warns with the timeout seconds, stalledPath, and cumulative budget, then returns give-up: the stalled file is quarantined, the slot is respawned, and the failure surfaces as a WorkerPoolDispatchError describing the timeout after N seconds.","triggerScenarios":"A one-item job whose every retry (with escalating timeouts) still went idle-silent: nextAttempt > maxTimeoutRetries selects this branch; stalledPath feeds both the quarantine set and the surfaced error text.","commonSituations":"A file that provably cannot finish parsing within any sane budget (multi-MB generated blob, pathological grammar input), native parser hangs on a specific construct, or machines where even the final escalated timeout is unrealistic.","solutions":["Take stalledPath from the warn/error and exclude that file from indexing (or split/shrink it at the source)","Check whether the file parses at all in isolation with a generous budget — if it hangs deterministically, report it upstream as a parser-hang repro","Raise the timeout family (GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS + maxTimeoutRetries/backoff) only if your hardware is uniformly slow, not for one poison file","Re-run analyze after exclusion — quarantine is per-run, so the fix must be at the input or config level to stick"],"exampleFix":"# before\n# stalledPath=src/generated/schema.giant.ts quarantined every run\nnpx gitnexus analyze\n# after\necho 'src/generated/schema.giant.ts' >> .gitnexusignore\nnpx gitnexus analyze   # no quarantine, run completes","handlingStrategy":"retry","validationCode":"// Catch the terminal give-up, quarantine the file, retry the run without it:\ntry {\n  await runAnalyze();\n} catch (e) {\n  if (e instanceof WorkerPoolDispatchError) {\n    const stalled = e.message.match(/idle timeout after [\\s\\S]*?/);\n    const file = extractPath(e.message) ?? extractPath(stalled?.[0] ?? '');\n    if (file) { appendIgnore(file); await runAnalyze(); return; }\n  }\n  throw e;\n}","typeGuard":null,"tryCatchPattern":"// Pattern: one bounded retry after removing the poison input — never retry unchanged\ntry {\n  await runAnalyze();\n} catch (e) {\n  if (!(e instanceof WorkerPoolDispatchError)) throw e;\n  const stalled = e.stalledPath ?? parseStalledPath(e.message);\n  if (!stalled) throw e;\n  appendIgnore(stalled);\n  await runAnalyze(); // exactly one retry, with the input changed\n}","preventionTips":["Persist ignore entries for every quarantined stalledPath — the per-run quarantine does not survive re-runs","Verify a suspected parser hang in isolation with a generous timeout before reporting it","Keep the timeout family sized so only true poison files reach this path, not ordinary slow files"],"tags":["worker-pool","timeout","retries-exhausted","quarantine","dispatch-error"],"backgroundTag":"timeout-retries-exhausted","analyzedSha":"0d1aed942f0e8b5d3bac27519fff441aceea722d","analyzedAt":"2026-08-20T23:29:22.980Z","contentChangedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}