{"record":{"id":"8d8f4c4c49b6fef7","repo":"mastra-ai/mastra","slug":"concurrency-limit-reached-cannot-enqueue-task-for","errorCode":null,"errorMessage":"Concurrency limit reached, cannot enqueue task for tool \"${task.toolName}\"","messagePattern":"Concurrency limit reached, cannot enqueue task for tool \"(.+?)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"packages/core/src/background-tasks/manager.ts","lineNumber":320,"sourceCode":"      this.registerTaskContext(task.id, context);\n    }\n\n    const storage = await this.getStorage();\n    await storage.createTask(task);\n\n    const canRun = await this.checkConcurrency(task.agentId);\n\n    if (canRun) {\n      await this.dispatch(task);\n      return { task };\n    }\n\n    // Backpressure\n    switch (this.config.backpressure) {\n      case 'reject':\n        this.deregisterTaskContext(task.id);\n        await storage.deleteTask(task.id);\n        throw new Error(`Concurrency limit reached, cannot enqueue task for tool \"${task.toolName}\"`);\n\n      case 'fallback-sync':\n        this.deregisterTaskContext(task.id);\n        await storage.deleteTask(task.id);\n        return { task, fallbackToSync: true };\n\n      case 'queue':\n      default:\n        // Task stays pending in storage, will be dispatched when a slot opens\n        return { task };\n    }\n  }\n\n  async cancel(taskId: string): Promise<void> {\n    if (this.initPromise) await this.initPromise;\n    const storage = await this.getStorage();\n    let task = await storage.getTask(taskId);\n    if (!task) {","sourceCodeStart":302,"sourceCodeEnd":338,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/background-tasks/manager.ts#L302-L338","documentation":"When the per-agent concurrency limit is reached and config.backpressure is 'reject', enqueue() throws, deletes the already-created task record, and refuses the task. This is deliberate backpressure: instead of queueing unboundedly, the caller is told the system is saturated.","triggerScenarios":"Enqueueing more concurrent tasks for the same agentId than the configured concurrency limit with backpressure: 'reject'; bursts of parallel tool calls each creating background tasks; a stuck/suspended task occupying a concurrency slot.","commonSituations":"Fan-out agents spawning many background tool calls at once; misconfigured (too low) concurrency limit; tasks that never complete holding slots; load spikes during batch jobs.","solutions":["Set config.backpressure to 'fallback-sync' (or 'wait' if available) to degrade gracefully instead of throwing.","Raise the concurrency limit for the agent in manager config.","Retry the enqueue with exponential backoff (the thrown error is retryable).","Audit for leaked slots: tasks stuck in non-terminal states; cancel or complete them to free capacity."],"exampleFix":"// before\nconst manager = new BackgroundTaskManager({ backpressure: 'reject', concurrency: 2 });\n// after\nconst manager = new BackgroundTaskManager({ backpressure: 'fallback-sync', concurrency: 8 });\n// or wrap enqueue in retry:\ntry { await manager.enqueue(p); } catch (e) { await sleep(backoff); retry(); }","handlingStrategy":"retry","validationCode":"const inflight = await countInflightTasks(agentId); // e.g. storage listTasks filtered\nif (inflight >= concurrencyLimit) await waitForSlot();","typeGuard":null,"tryCatchPattern":"try {\n  return await manager.enqueue(payload);\n} catch (e) {\n  if ((e as Error).message.startsWith('Concurrency limit reached')) {\n    await sleep(backoffMs);\n    return manager.enqueue(payload); // retry with backoff\n  }\n  throw e;\n}","preventionTips":["Choose backpressure: 'fallback-sync' when rejection is unacceptable.","Size the concurrency limit to real agent capacity.","Retry enqueues with exponential backoff on limit errors.","Monitor for tasks stuck in non-terminal states that hog slots."],"tags":["background-tasks","backpressure","concurrency"],"backgroundTag":"concurrency-limit-reached","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}