{"record":{"id":"209868c755fc6b73","repo":"ruvnet/ruflo","slug":"agent-this-id-has-reached-max-concurrent-tasks","errorCode":null,"errorMessage":"Agent ${this.id} has reached max concurrent tasks","messagePattern":"Agent (.+?) has reached max concurrent tasks","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/integration/src/agentic-flow-agent.ts","lineNumber":495,"sourceCode":"   * to agentic-flow's Agent.execute() which leverages:\n   * - Flash Attention for 2.49x-7.47x faster processing\n   * - SONA learning for real-time adaptation\n   * - AgentDB for 150x-12,500x faster memory retrieval\n   *\n   * @param task - Task to execute\n   * @returns Task result with output or error\n   */\n  async executeTask(task: Task): Promise<TaskResult> {\n    this.ensureInitialized();\n\n    // Validate agent is available\n    if (this.status === 'terminated' || this.status === 'error') {\n      throw new Error(`Agent ${this.id} is not available (status: ${this.status})`);\n    }\n\n    // Check concurrent task limit\n    if (this.currentTaskCount >= this.config.maxConcurrentTasks) {\n      throw new Error(`Agent ${this.id} has reached max concurrent tasks`);\n    }\n\n    this.currentTask = task;\n    this.currentTaskCount++;\n    this.status = 'busy';\n    this.taskStartTime = Date.now();\n    this.lastActivity = new Date();\n\n    this.emit('task-started', {\n      agentId: this.id,\n      taskId: task.id,\n      taskType: task.type,\n    });\n\n    try {\n      let output: unknown;\n\n      // ADR-001: Delegate to agentic-flow when available for optimized execution","sourceCodeStart":477,"sourceCodeEnd":513,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/integration/src/agentic-flow-agent.ts#L477-L513","documentation":"Thrown by AgenticFlowAgent#executeTask (v3/@claude-flow/integration/src/agentic-flow-agent.ts:495) when currentTaskCount >= config.maxConcurrentTasks. The agent enforces its own concurrency budget before accepting work; note the counter is incremented synchronously on accept, so it reflects in-flight tasks.","triggerScenarios":"Dispatching more parallel tasks than the agent's maxConcurrentTasks (default is small, often 1); fire-and-forget executeTask calls that stack up; a worker pool that keeps assigning to the same agent instead of load-balancing; an agent stuck 'busy' because a prior task never resolved and the count never decremented.","commonSituations":"Raising parallelism (Promise.all over many tasks) without raising maxConcurrentTasks in the agent config; a hung external call inside a task leaking a slot; tests that await nothing and over-submit.","solutions":["Raise maxConcurrentTasks in the AgentConfig when the agent is expected to handle more parallel work.","Track in-flight promises per agent and only dispatch when below the limit (simple semaphore around executeTask).","Use a worker pool that respects agent capacity instead of round-robin dispatch.","If counts look stuck, verify every code path decrements currentTaskCount (a never-settling task leaks slots) and add timeouts to task execution."],"exampleFix":"// before\nawait Promise.all(tasks.map((t) => agent.executeTask(t))); // maxConcurrentTasks = 1\n\n// after\nconst sem = new Semaphore(agent.config.maxConcurrentTasks);\nawait Promise.all(tasks.map((t) => sem.withLock(() => agent.executeTask(t))));\n// or: new AgenticFlowAgent({ ...cfg, maxConcurrentTasks: 10 })","handlingStrategy":"validation","validationCode":"class Semaphore {\n  private active = 0; private queue: (() => void)[] = [];\n  constructor(private n: number) {}\n  async withLock<T>(fn: () => Promise<T>): Promise<T> {\n    if (this.active >= this.n) await new Promise<void>((r) => this.queue.push(r));\n    this.active++;\n    try { return await fn(); } finally { this.active--; this.queue.shift()?.(); }\n  }\n}\n// usage: sem.withLock(() => agent.executeTask(task))","typeGuard":"function canAccept(agent: { currentTaskCount: number; config: { maxConcurrentTasks: number } }): boolean {\n  return agent.currentTaskCount < agent.config.maxConcurrentTasks;\n}","tryCatchPattern":"try {\n  return await agent.executeTask(task);\n} catch (e) {\n  if (/max concurrent tasks/.test((e as Error).message)) {\n    await waitForSlot(agent); // poll currentTaskCount or subscribe to completion events\n    return agent.executeTask(task);\n  }\n  throw e;\n}","preventionTips":["Size maxConcurrentTasks to your dispatch parallelism.","Bound caller-side concurrency with a semaphore equal to the agent limit.","Add timeouts to tasks so a hung task cannot permanently consume a slot."],"tags":["concurrency","resource-limit","agent","backpressure"],"backgroundTag":"concurrency-limit-exceeded","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}