{"record":{"id":"a0aed4849ce71985","repo":"ruvnet/ruflo","slug":"worker-this-id-at-capacity-maxtasks-tasks","errorCode":null,"errorMessage":"Worker ${this.id} at capacity (${maxTasks} tasks)","messagePattern":"Worker (.+?) at capacity \\((.+?) tasks\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/integration/src/worker-base.ts","lineNumber":408,"sourceCode":"  }\n\n  // ===== Task Execution =====\n\n  /**\n   * Execute a task with wrapper logic\n   *\n   * Handles load tracking, metrics, and error handling.\n   *\n   * @param task - Task to execute\n   * @returns Task result with metrics\n   */\n  async executeTask(task: Task): Promise<TaskResult> {\n    this.ensureInitialized();\n\n    // Check capacity\n    const maxTasks = this.config.maxConcurrentTasks || 1;\n    if (this.currentTaskCount >= maxTasks) {\n      throw new Error(`Worker ${this.id} at capacity (${maxTasks} tasks)`);\n    }\n\n    this.currentTaskCount++;\n    this.updateLoad();\n    this.status = 'busy';\n    const startTime = Date.now();\n\n    this.emit('task-started', { workerId: this.id, taskId: task.id });\n\n    try {\n      // Execute via subclass implementation\n      const output = await this.execute(task);\n\n      const duration = Date.now() - startTime;\n\n      // Update metrics\n      this.updateMetricsSuccess(duration, output.tokensUsed);\n","sourceCodeStart":390,"sourceCodeEnd":426,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/integration/src/worker-base.ts#L390-L426","documentation":"WorkerBase.executeTask refuses work once currentTaskCount reaches config.maxConcurrentTasks (default 1). The check runs before the task starts; the counter is decremented when execution finishes, so the worker only accepts work below the cap — it does not queue.","triggerScenarios":"Dispatching a second concurrent task to a worker with maxConcurrentTasks unset (default 1) while the first is still running — e.g. Promise.all over the same worker instance.","commonSituations":"Assuming the worker queues internally (it throws instead); forgetting the default cap is 1; fanning out N tasks to one worker without raising the setting.","solutions":["Serialize per worker: await each executeTask before starting the next","Raise config.maxConcurrentTasks — only if the subclass's execute() is actually safe to run concurrently","Dispatch through a worker pool so busy workers are routed around instead of thrown on"],"exampleFix":"// before\nawait Promise.all([t1, t2].map(t => worker.executeTask(t))); // second call throws: cap is 1\n\n// after\nfor (const t of [t1, t2]) {\n  await worker.executeTask(t); // serialized, stays under the cap\n}\n// or, when execute() is concurrency-safe:\nnew MyWorker({ id, maxConcurrentTasks: 4 });","handlingStrategy":"validation","validationCode":"// Check the cap before dispatching; track occupancy via task events\nconst max = worker.config.maxConcurrentTasks ?? 1;\nconst busy = inFlightCount.get(worker.id) ?? 0; // increment on 'task-started', decrement on completion\nif (busy >= max) {\n  await waitForWorkerIdle(worker.id); // or route to another worker\n}\nawait worker.executeTask(task);","typeGuard":null,"tryCatchPattern":"try {\n  await worker.executeTask(task);\n} catch (e) {\n  if (e instanceof Error && /at capacity/.test(e.message)) {\n    // backpressure: requeue the task or pick another worker; do not busy-retry\n  }\n  throw e;\n}","preventionTips":["Serialize per-worker calls or route through a pool that skips busy workers","Set maxConcurrentTasks deliberately, and only when execute() is reentrant-safe","Watch 'task-started'/'task-completed' events to know real occupancy before dispatch"],"tags":["capacity","concurrency","worker","backpressure"],"backgroundTag":"capacity-exceeded","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}