{"record":{"id":"02b788eb12712ab1","repo":"abhigyanpatwari/GitNexus","slug":"worker-workerindex-timed-out-retiring-without","errorCode":null,"errorMessage":"Worker ${workerIndex} timed out; retiring without immediate terminate to avoid aborting native parser state.","messagePattern":"Worker (.+?) timed out; retiring without immediate terminate to avoid aborting native parser state\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"gitnexus/src/core/ingestion/workers/worker-pool.ts","lineNumber":1564,"sourceCode":"          cleanupRetired();\n        };\n        const onRetiredMessageError = () => terminateWhenBackInJs();\n        const record: RetiredWorkerRecord = {\n          worker,\n          workerIndex,\n          reason,\n          cleanup: cleanupRetired,\n          terminate: terminateRetired,\n          safeToTerminate: false,\n          safePoint,\n        };\n        retiredWorkers.add(record);\n        worker.on('message', onRetiredMessage);\n        worker.once('error', onRetiredError);\n        worker.once('exit', onRetiredExit);\n        worker.once('messageerror', onRetiredMessageError);\n        (worker as Worker & { unref?: () => void }).unref?.();\n        logger.warn(\n          { workerIndex, reason },\n          `Worker ${workerIndex} timed out; retiring without immediate terminate to avoid aborting native parser state.`,\n        );\n      };\n\n      const removeWorkerFromSlot = async (\n        workerIndex: number,\n        mode: WorkerRemovalMode,\n        reason: string,\n      ): Promise<void> => {\n        const existing = workers[workerIndex];\n        workers[workerIndex] = undefined;\n        if (!existing) return;\n        if (mode === 'retire') {\n          retireWorkerAfterTimeout(existing, workerIndex, reason);\n          return;\n        }\n        // Recovery must settle before dispatch returns, but a failed thread","sourceCodeStart":1546,"sourceCodeEnd":1582,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/0d1aed942f0e8b5d3bac27519fff441aceea722d/gitnexus/src/core/ingestion/workers/worker-pool.ts#L1546-L1582","documentation":"When a worker exceeds its idle/parse timeout, the pool retires it WITHOUT an immediate terminate(): terminating a worker mid-native-parser call risks the process-wide N-API abort (#2432). Instead the worker record is marked safeToTerminate: false, a safe-point promise is captured, listeners are armed, the worker is unref'd, and this warn records the retirement with the worker index and reason.","triggerScenarios":"A parse job blowing its timeout budget on a worker — the retire path fires: the slot is replaced by a fresh worker while the old one is drained/awaited at its safe point rather than killed; the warn names workerIndex and the timeout reason.","commonSituations":"Parser-hostile files (deeply nested/generated code) stalling a worker past GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS, overloaded CI machines making legit parses look idle, or overly aggressive timeout overrides.","solutions":["Identify the stalling file from the retirement reason / subsequent job warns and exclude or shrink it","Raise GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS (or the configured idle timeout) if your hardware routinely needs longer per sub-batch","Expect job-level handling to follow: the stalled job is split/retried/quarantined independently — this warn is about the worker, not the file outcome","If retirements cluster on one language/grammar, check for a slow source-built native grammar and prefer the prebuilt binary"],"exampleFix":"# before\nexport GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS=   # default too low for big files → retire warn\n# after\nexport GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS=120000   # sub-batches finish in-budget, no retire","handlingStrategy":"fallback","validationCode":"// Budget timeouts to your hardware before the run:\nconst slowCi = Number(process.env.GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS ?? 0) < 60000;\nif (slowCi) process.env.GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS = '120000';","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Exclude or shrink files that stall sub-batches; retirement is the symptom, the file is the cause","Track retire warns per language — clusters point at a slow source-built grammar (prefer prebuilts)","Trust the no-immediate-terminate design: it prevents a process-wide N-API abort during retirement"],"tags":["worker-pool","timeout","retirement","native-code","parse-jobs"],"backgroundTag":"worker-heartbeat-timeout","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"}