{"record":{"id":"616c52fee153bbcf","repo":"ruvnet/ruflo","slug":"bulkhead-this-options-name-is-full-max-concu","errorCode":null,"errorMessage":"Bulkhead '${this.options.name}' is full. Max concurrent: ${this.options.maxConcurrent}, queue: ${this.options.maxQueue}","messagePattern":"Bulkhead '(.+?)' is full\\. Max concurrent: (.+?), queue: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/shared/src/resilience/bulkhead.ts","lineNumber":110,"sourceCode":"  constructor(options: BulkheadOptions) {\n    super();\n    this.options = { ...DEFAULT_OPTIONS, ...options };\n  }\n\n  /**\n   * Execute a function within the bulkhead\n   */\n  async execute<T>(fn: () => Promise<T>): Promise<T> {\n    // If there's room for execution, run immediately\n    if (this.active < this.options.maxConcurrent) {\n      return this.runNow(fn);\n    }\n\n    // Check if queue is full\n    if (this.queue.length >= this.options.maxQueue) {\n      this.rejected++;\n      this.options.onRejected?.('full');\n      throw new Error(`Bulkhead '${this.options.name}' is full. Max concurrent: ${this.options.maxConcurrent}, queue: ${this.options.maxQueue}`);\n    }\n\n    // Add to queue\n    return this.addToQueue(fn);\n  }\n\n  /**\n   * Get current statistics\n   */\n  getStats(): BulkheadStats {\n    return {\n      active: this.active,\n      queued: this.queue.length,\n      maxConcurrent: this.options.maxConcurrent,\n      maxQueue: this.options.maxQueue,\n      completed: this.completed,\n      rejected: this.rejected,\n      timedOut: this.timedOut,","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/shared/src/resilience/bulkhead.ts#L92-L128","documentation":"Bulkhead is a resilience4j-style concurrency limiter. execute() runs fn immediately while active < maxConcurrent, otherwise enqueues while the queue holds fewer than maxQueue entries. When both execution slots and queue slots are exhausted it increments the rejected counter, fires options.onRejected('full'), and throws — deliberate fail-fast overload protection rather than unbounded queuing.","triggerScenarios":"Issuing more than maxConcurrent + maxQueue concurrent execute() calls; slow wrapped functions (downstream HTTP/DB calls) holding all execution slots while new submissions keep arriving; a burst of fan-out work (e.g. Promise.all over a large array) funneled through one small bulkhead.","commonSituations":"maxConcurrent/maxQueue sized for average rather than peak load; a degraded downstream dependency so slots never free; load tests or traffic spikes revealing the cap; missing onRejected handler so rejections only surface as exceptions.","solutions":["Raise maxConcurrent and/or maxQueue in the Bulkhead options to cover peak concurrency.","Register options.onRejected to shed load gracefully (log, 429, drop, backpressure) instead of relying on the throw.","Check getStats() before submitting and defer when active and queue are near their maxima.","Attach timeouts/retries to the wrapped fn so execution slots are released promptly even when downstream hangs."],"exampleFix":"// before\nconst bulkhead = new Bulkhead({ name: 'api', maxConcurrent: 5, maxQueue: 10 });\nconst r = await bulkhead.execute(() => callApi()); // throws at 5 active + 10 queued\n\n// after\nconst bulkhead = new Bulkhead({\n  name: 'api',\n  maxConcurrent: 20,\n  maxQueue: 100,\n  onRejected: (reason) => metrics.increment('bulkhead.rejected', { reason }),\n});","handlingStrategy":"fallback","validationCode":"const s = bulkhead.getStats();\n// active and queue occupancy vs your configured maxima\nif (s.active >= opts.maxConcurrent && s.queue >= opts.maxQueue) {\n  // at capacity: defer, shed load, or throttle before calling execute\n}","typeGuard":null,"tryCatchPattern":"try {\n  result = await bulkhead.execute(fn);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('is full. Max concurrent:')) {\n    result = await degradeOrEnqueueElsewhere(); // serve a fallback instead of crashing\n  } else {\n    throw e;\n  }\n}","preventionTips":["Size maxConcurrent and maxQueue from measured peak load plus headroom, not averages.","Always configure onRejected so rejections are observable before they become exceptions.","Attach timeouts to the wrapped fn so execution slots free even when downstream hangs.","Bound caller concurrency upstream (queues, worker pools) so submissions never exceed bulkhead capacity."],"tags":["resilience","bulkhead","concurrency","backpressure"],"backgroundTag":"bulkhead-full","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}