mastra-ai/mastra · warning · Error
Concurrency limit reached, cannot restart task "${taskId}" —
Error message
Concurrency limit reached, cannot restart task "${taskId}" — retry once a slot is available What it means
Like resume, restart() bypasses the queue/dispatch fallback path, so before dispatching it checks the agent's concurrency limit. When no slot is available it throws rather than silently leaving the task running while doing nothing; the caller should retry once a slot frees.
Source
Thrown at packages/core/src/background-tasks/manager.ts:493
const task = await storage.getTask(taskId);
if (!task) {
throw new Error(`Task not found: ${taskId}`);
}
if (task.status !== 'running') {
throw new Error(`Cannot restart task in status '${task.status}' (expected 'running')`);
}
if (context) {
this.registerTaskContext(task.id, context);
}
const canRun = await this.checkConcurrency(task.agentId);
if (!canRun) {
// Restart sits outside the queue/fallback-sync paths — there's no
// synchronous caller to fall back to, and silently leaving the task
// running hides the failure from the caller. Throw and let the
// caller retry once a slot frees.
throw new Error(`Concurrency limit reached, cannot restart task "${taskId}" — retry once a slot is available`);
}
await this.dispatch(task, true);
return task;
}
async getTask(taskId: string): Promise<BackgroundTask | null> {
const storage = await this.getStorage();
return storage.getTask(taskId);
}
async listTasks(filter: TaskFilter = {}): Promise<TaskListResult> {
const storage = await this.getStorage();
return storage.listTasks(filter);
}
/**View on GitHub (pinned to 75dd419e61)
Solutions
- Catch the error and retry restart with exponential backoff.
- Limit restart parallelism (e.g. process restarts in small batches with p-limit).
- Increase the agent's concurrency limit if restart storms are routine.
Example fix
// before
await Promise.all(ids.map(id => manager.restart(id))); // some throw on concurrency
// after
const limit = pLimit(maxConcurrency);
for (const id of ids) {
limit(() => manager.restart(id)).catch(e => {
if (String(e).includes('Concurrency limit reached')) retryLater(id);
});
} Defensive patterns
Strategy: retry
Try / catch
async function restartWithBackoff(taskId, maxAttempts = 5) {
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
return await manager.restart(taskId);
} catch (e) {
if (!e.message.includes('Concurrency limit reached') || attempt === maxAttempts) throw e;
await new Promise(r => setTimeout(r, 2 ** attempt * 1000));
}
}
} Prevention
- Throttle bulk restarts to stay within the agent concurrency budget.
- Monitor per-agent running-task counts and pause restart storms above threshold.
- Prefer raising concurrency config over aggressive retry loops when restarts are routine.
When it happens
Trigger: Calling manager.restart(taskId) when the task's agent already runs the maximum number of concurrent tasks allowed by its concurrency configuration.
Common situations: Bulk-restarting many running tasks during an incident response while the agent's concurrency budget is exhausted; deployments with low per-agent concurrency limits under heavy load.
Related errors
- Concurrency limit reached, cannot resume task "${taskId}" —
- Concurrency limit reached, cannot enqueue task for tool "${t
- MastraFactory.prepare() called twice
- Factory kickoff lease was lost before completion.
- ${file} is in use by another process — is another Mastra Cod
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/f3b20d16a5516bdf.
Report an issue: GitHub.