{"record":{"id":"6b46ea86deb7ada5","repo":"abhigyanpatwari/GitNexus","slug":"worker-pool-circuit-breaker-tripped-reason-subs","errorCode":null,"errorMessage":"Worker pool circuit breaker tripped${reason}. Subsequent dispatches require a fresh pool instance.","messagePattern":"Worker pool circuit breaker tripped(.+?)\\. Subsequent dispatches require a fresh pool instance\\.","errorType":"exception","errorClass":"WorkerPoolDispatchError","httpStatus":null,"severity":"error","filePath":"gitnexus/src/core/ingestion/workers/worker-pool.ts","lineNumber":1282,"sourceCode":"  ).then(() => undefined);\n\n  const dispatch = async <TInput, TResult>(\n    items: TInput[],\n    onProgress?: (filesProcessed: number) => void,\n    chunkHash?: string,\n  ): Promise<TResult[]> => {\n    // Await the initial-spawn readiness gate (F13). On first dispatch\n    // this blocks for up to poolOptions.workerReadyTimeoutMs while every initial\n    // worker's `{type:'ready'}` handshake is checked; on subsequent\n    // dispatches the promise is already settled and resolves\n    // synchronously. Slots whose initial worker crashed in top-of-\n    // script init have been dropped from `activeSlots` by the gate\n    // before this point — they don't surface here as \"no active\n    // workers\" until *all* initial slots fail.\n    await initialReadyGate;\n    if (poolBroken) {\n      const reason = poolFailure ? `: ${poolFailure.message}` : '';\n      throw new WorkerPoolDispatchError(\n        `Worker pool circuit breaker tripped${reason}. ` +\n          `Subsequent dispatches require a fresh pool instance.`,\n        [],\n      );\n    }\n    if (items.length === 0) return [];\n    if (activeSlots.size === 0) {\n      const detail =\n        initialReadinessFailures.length > 0\n          ? ` after initial ready handshake: ${initialReadinessFailures.join('; ')}`\n          : '';\n      // The bounded self-heal exhausted (or short-circuited a deterministic\n      // crash-loop). Classify automatically so the caller renders the real\n      // cause without consulting any operator flag (#1741).\n      const crashClass: StartupCrashClass = deterministicStartupDetected\n        ? 'deterministic-startup'\n        : 'transient-exhausted';\n      throw new WorkerPoolInitializationError(","sourceCodeStart":1264,"sourceCodeEnd":1300,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/gitnexus/src/core/ingestion/workers/worker-pool.ts#L1264-L1300","documentation":"Thrown by `dispatch()` when the pool's circuit breaker has already tripped (`poolBroken === true`). The circuit breaker is set when the pool suffers a catastrophic, non-recoverable failure; once set, every subsequent dispatch to the SAME pool instance re-throws this `WorkerPoolDispatchError`. The pool is dead — the message explicitly states that subsequent dispatches require a fresh pool instance. The error carries the triggering `poolFailure.message` as the reason.","triggerScenarios":"Calling `pool.dispatch(...)` a second (or later) time after the pool already broke during a prior dispatch — e.g. an unrecoverable worker-death cascade tripped the breaker, and the caller did not recreate the pool before the next chunk dispatch.","commonSituations":"A parse loop that reuses one pool across many chunks and continues dispatching after an earlier chunk's fatal pool failure; a caller that swallowed a prior dispatch error without checking whether the pool was still usable.","solutions":["Create a FRESH pool instance (`createWorkerPool(...)`) before dispatching again — a broken pool cannot be reset.","Inspect the `reason` (the original `poolFailure.message`) to fix the underlying cause before recreating the pool.","After a dispatch throws, always discard the pool reference and rebuild it for the next batch rather than retrying on the same instance."],"exampleFix":"// before — reuse a pool after it broke\nconst pool = createWorkerPool(url);\ntry { await pool.dispatch(batchA); } catch { /* swallowed */ }\nawait pool.dispatch(batchB); // → Worker pool circuit breaker tripped...\n\n// after — recreate the pool after a failure\nlet pool = createWorkerPool(url);\ntry {\n  await pool.dispatch(batchA);\n} catch {\n  pool = createWorkerPool(url); // fresh instance\n}\nawait pool.dispatch(batchB);","handlingStrategy":"fallback","validationCode":null,"typeGuard":"import { WorkerPoolDispatchError } from 'gitnexus/dist/core/ingestion/workers/worker-pool.js';\n\nfunction isPoolBroken(err): err is WorkerPoolDispatchError {\n  return err instanceof WorkerPoolDispatchError\n    || /circuit breaker tripped/i.test(err.message);\n}","tryCatchPattern":"// Recreate the pool after a circuit-breaker trip — a broken pool is not reusable.\nlet pool = createWorkerPool(url);\nfor (const batch of batches) {\n  try {\n    await pool.dispatch(batch);\n  } catch (err) {\n    if (/circuit breaker tripped/i.test(err.message)) {\n      pool = createWorkerPool(url); // fresh instance, fix root cause first\n      continue;\n    }\n    throw err;\n  }\n}","preventionTips":["Never reuse a pool after a dispatch throws a WorkerPoolDispatchError — discard and recreate it.","Inspect the `reason` in the message to fix the underlying pool failure before recreating.","Scope a pool to one logical batch group so a breaker trip only invalidates that group."],"tags":["worker-pool","circuit-breaker","dispatch","resilience"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}