{"record":{"id":"e57b5204a003724d","repo":"abhigyanpatwari/GitNexus","slug":"request-failed-after-retries-http-response-stat","errorCode":null,"errorMessage":"Request failed after retries (HTTP ${response.status})","messagePattern":"Request failed after retries \\(HTTP (.+?)\\)","errorType":"exception","errorClass":"ResilientFetchExhaustedError","httpStatus":null,"severity":"error","filePath":"gitnexus-shared/src/integrations/resilient-fetch.ts","lineNumber":248,"sourceCode":"        // also do NOT call recordSuccess: a 401 sandwiched between\n        // 5xx responses would otherwise erase the running outage\n        // signal. The breaker's neutral path leaves state untouched.\n        breaker.recordNeutral();\n        return outcome.resp;\n\n      case 'terminal-network':\n        // Either `AbortSignal.timeout()` fired locally OR an external\n        // caller cancelled the request via AbortController. The server\n        // never had a chance to answer; this reflects the user's\n        // network or an explicit cancel, not registry health. Don't\n        // punish the breaker AND don't reset its outage signal.\n        breaker.recordNeutral();\n        throw outcome.err;\n\n      case 'retryable-status':\n        if (attempt + 1 >= retryConfig.maxAttempts) {\n          breaker.recordFailure();\n          throw new ResilientFetchExhaustedError(outcome.resp);\n        }\n        await sleep(\n          computeBackoffMs(\n            attempt,\n            retryConfig.baseDelayMs,\n            retryConfig.capDelayMs,\n            outcome.afterMs,\n            random,\n          ),\n        );\n        break;\n\n      case 'retryable-network':\n        if (attempt + 1 >= retryConfig.maxAttempts) {\n          breaker.recordFailure();\n          throw outcome.err;\n        }\n        await sleep(","sourceCodeStart":230,"sourceCodeEnd":266,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/aac7515d2a8c50a1f8f923c6fb77218b333560d6/gitnexus-shared/src/integrations/resilient-fetch.ts#L230-L266","documentation":"During idle-timeout retries, a slot's respawn counter exceeded poolOptions.maxRespawnsPerSlot, so the pool drops (retires) that slot instead of respawning its worker again. Available parallelism shrinks permanently for the run; if enough slots drop or the breaker also trips, dispatch degrades or fails. This is the budget path that stops infinite respawn loops on a persistently dying slot.","triggerScenarios":"respawnCount[workerIndex] > poolOptions.maxRespawnsPerSlot after an idle-timeout retry decision — a slot whose workers keep dying and being respawned within one run; default budget is DEFAULT_MAX_RESPAWNS_PER_SLOT, overridable via options or GITNEXUS_WORKER_MAX_RESPAWNS_PER_SLOT.","commonSituations":"Workers OOM-crashing on a huge file faster than the budget refills; native addon (tree-sitter grammar) segfaulting on specific inputs; machines where worker threads are killed by an external supervisor (OOM killer, container limits).","solutions":["Find why workers die rather than raising the budget first: check for worker crash logs (exit codes, OOM killer, segfaults) preceding this warn","If deaths are OOM, raise per-worker memory or shrink sub-batches (GITNEXUS_WORKER_SUB_BATCH_MAX_BYTES)","Raise GITNEXUS_WORKER_MAX_RESPAWNS_PER_SLOT only to ride through transient environments","Update/rebuild the vendored tree-sitter grammars if a native crash is suspected (prebuild vs platform mismatch)"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"const isWorkerPoolDispatchError = (e: unknown): e is Error & { quarantine?: unknown } =>\n  e instanceof Error && /Worker pool/.test(e.message);","tryCatchPattern":"try {\n  await pool.dispatch(job);\n} catch (e) {\n  if (isWorkerPoolDispatchError(e)) {\n    // slot dropped: parallelism is reduced but the pool may still drain remaining jobs;\n    // decide between degrading gracefully and aborting to re-run with a higher\n    // GITNEXUS_WORKER_MAX_RESPAWNS_PER_SLOT after fixing worker deaths\n    logger.warn(`slot loss during dispatch: ${e.message}`);\n  }\n}","preventionTips":["Diagnose why workers die (OOM killer, segfaults) before raising the respawn budget","Set container/OOM limits above per-worker peak memory","Rebuild vendored grammars after Node major-version upgrades to avoid native crashes"],"tags":["worker-pool","respawn","timeout","ingestion"],"backgroundTag":"worker-respawn-limit-exceeded","analyzedSha":"aac7515d2a8c50a1f8f923c6fb77218b333560d6","analyzedAt":"2026-08-20T23:29:22.980Z","contentChangedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}