mastra-ai/mastra · error · Error

BackgroundTaskManager is shutting down, cannot resume tasks

Error message

BackgroundTaskManager is shutting down, cannot resume tasks

What it means

resume(taskId, resumeData) refuses to resume suspended tasks once shutdown has started. Resuming re-dispatches a workflow run and needs live workers/pubsub, which are unavailable during teardown. The library throws instead of resuming into a dying process.

Source

Thrown at packages/core/src/background-tasks/manager.ts:414

          runId: taskId,
        });
      }
      return;
    }
  }

  /**
   * Resume a suspended task. The tool executor must be re-registered via
   * `registerTaskContext(taskId, ...)` before calling this if the original
   * registration is gone (e.g. process restart) — the manager doesn't
   * rehydrate executor closures from storage.
   *
   * `resumeData` is forwarded to the tool's `execute` options on the
   * resumed run.
   */
  async resume(taskId: string, resumeData?: unknown): Promise<BackgroundTask> {
    if (this.shuttingDown) {
      throw new Error('BackgroundTaskManager is shutting down, cannot resume tasks');
    }
    if (!this.#mastra) {
      throw new Error('Mastra is not registered with this manager');
    }

    if (this.initPromise) await this.initPromise;

    const storage = await this.getStorage();
    const task = await storage.getTask(taskId);
    if (!task) {
      throw new Error(`Task not found: ${taskId}`);
    }
    if (task.status !== 'suspended') {
      throw new Error(`Cannot resume task in status '${task.status}' (expected 'suspended')`);
    }

    const canRun = await this.checkConcurrency(task.agentId);
    if (!canRun) {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Defer resume until after restart: check manager.shuttingDown and persist resumeData for post-restart replay.
  2. Perform shutdown drain first: resume/complete suspended tasks, then call shutdown().
  3. Re-create the manager (new process/instance) and resume there once shuttingDown is false.
  4. Gate auto-resume handlers on the shutdown flag.

Example fix

// before
await manager.resume(taskId, data); // may throw during shutdown
// after
if (manager.shuttingDown) {
  await saveForRestart(taskId, data); // replay after restart
} else {
  await manager.resume(taskId, data);
}
Defensive patterns

Strategy: validation

Validate before calling

if (manager.shuttingDown) {
  await saveForRestart(taskId, resumeData);
  return;
}

Try / catch

try {
  await manager.resume(taskId, data);
} catch (e) {
  if ((e as Error).message.includes('shutting down, cannot resume')) {
    await persistResumeIntent(taskId, data); // replay after restart
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling manager.resume() during SIGTERM/shutdown handling; an auto-resume path (handleResume) firing while shutdown() runs; resuming background tasks from a request handler processed during drain.

Common situations: Deploy-time drain with pending suspended tasks; retry loops that keep calling resume while shutdown is in progress; tests tearing down managers while resume is still pending.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/9714e0e926be00c6. Report an issue: GitHub.