abhigyanpatwari/GitNexus · error
Worker ${workerIndex} parse job idle timeout exhausted retri
Error message
Worker ${workerIndex} parse job idle timeout exhausted retries; quarantining file and respawning slot. What it means
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.
Source
Thrown at gitnexus/src/core/ingestion/workers/worker-pool.ts:1941
timeoutSec: job.timeoutMs / 1000,
attempt: nextAttempt,
maxAttempts: poolOptions.maxTimeoutRetries + 1,
nextTimeoutSec: nextTimeout / 1000,
},
`Worker ${workerIndex} parse job idle timeout (single item). Retrying with ${nextTimeout / 1000}s timeout.`,
);
jobs.unshift({
...job,
attempt: nextAttempt,
timeoutMs: nextTimeout,
cumulativeTimeoutMs: nextCumulative,
});
return { kind: 'retry' };
}
const stalledPath = inFlightPath ?? itemPath(job.items[0]);
const excludes = stalledPath ? [stalledPath] : [];
logger.warn(
{
workerIndex,
timeoutSec: job.timeoutMs / 1000,
stalledPath,
cumulativeMs: job.cumulativeTimeoutMs,
},
`Worker ${workerIndex} parse job idle timeout exhausted retries; quarantining file and respawning slot.`,
);
return {
kind: 'give-up',
reason:
`Worker ${workerIndex} parse job idle timeout after ${job.timeoutMs / 1000}s ` +
`(single item${stalledPath ? `: ${stalledPath}` : ''}, ` +
`${job.estimatedBytes} bytes, last progress: ${lastProgress})`,
excludePaths: excludes,
};
};
View on GitHub (pinned to 0d1aed942f)
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
Example fix
# before # stalledPath=src/generated/schema.giant.ts quarantined every run npx gitnexus analyze # after echo 'src/generated/schema.giant.ts' >> .gitnexusignore npx gitnexus analyze # no quarantine, run completes
Defensive patterns
Strategy: retry
Validate before calling
// Catch the terminal give-up, quarantine the file, retry the run without it:
try {
await runAnalyze();
} catch (e) {
if (e instanceof WorkerPoolDispatchError) {
const stalled = e.message.match(/idle timeout after [\s\S]*?/);
const file = extractPath(e.message) ?? extractPath(stalled?.[0] ?? '');
if (file) { appendIgnore(file); await runAnalyze(); return; }
}
throw e;
} Try / catch
// Pattern: one bounded retry after removing the poison input — never retry unchanged
try {
await runAnalyze();
} catch (e) {
if (!(e instanceof WorkerPoolDispatchError)) throw e;
const stalled = e.stalledPath ?? parseStalledPath(e.message);
if (!stalled) throw e;
appendIgnore(stalled);
await runAnalyze(); // exactly one retry, with the input changed
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Worker ${workerIndex} parse job exhausted cumulative timeout
- Circuit '${key}' is open; retry in ${Math.ceil(retryAfterMs
- Request failed after retries (HTTP ${response.status})
- Worker ${workerIndex} timed out; retiring without immediate
- Conceptual job ${job.startIndex} died ${deaths} times unattr
AI-assisted analysis of abhigyanpatwari/GitNexus@0d1aed942f (2026-08-20).
Data as JSON: /api/errors/600e8d5d67558ec0.
Report an issue: GitHub.