mastra-ai/mastra · error · Error

BackgroundTaskManager is shutting down, cannot restart tasks

Error message

BackgroundTaskManager is shutting down, cannot restart tasks

What it means

restart() is refused while the BackgroundTaskManager is shutting down (shuttingDown flag set, e.g. during shutdown()/process exit). Starting new task executions during teardown could orphan work or race cleanup, so the manager throws instead.

Source

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

    await this.pubsub.publish(TOPIC_DISPATCH, {
      type: 'task.resume',
      data: { taskId, resumeData },
      runId: taskId,
    });

    return task;
  }

  /**
   * Restarts a previously running task. The tool executor is re-registered via
   * `registerTaskContext(taskId, ...)` because the original
   * registration is gone (e.g. process restart) — the manager doesn't
   * rehydrate executor closures from storage.
   *
   */
  async restart(taskId: string, context?: TaskContext): Promise<BackgroundTask> {
    if (this.shuttingDown) {
      throw new Error('BackgroundTaskManager is shutting down, cannot restart 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 !== 'running') {
      throw new Error(`Cannot restart task in status '${task.status}' (expected 'running')`);
    }

    if (context) {
      this.registerTaskContext(task.id, context);

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Move restart calls before shutdown, or reject queued restart requests once shutdown has begun.
  2. Catch this error and either re-create the manager/Mastra instance or defer the restart to a fresh process.
  3. Check an app-level 'shutting down' flag before issuing restart calls in signal handlers.

Example fix

// before
await manager.restart(taskId); // during SIGTERM handling
// after
if (!isShuttingDown) {
  await manager.restart(taskId);
} else {
  pendingRestarts.push(taskId); // replay after restart of process
}
Defensive patterns

Strategy: validation

Validate before calling

// app-level gate (manager.shuttingDown is private)
let managerShuttingDown = false;
async function safeRestart(taskId) {
  if (managerShuttingDown) throw new Error('deferred: manager shutting down');
  return manager.restart(taskId);
}
// set managerShuttingDown = true before calling manager.shutdown()

Try / catch

try {
  await manager.restart(taskId);
} catch (e) {
  if (e.message === 'BackgroundTaskManager is shutting down, cannot restart tasks') {
    deferredRestarts.push(taskId); // replay after new manager is up
  } else throw e;
}

Prevention

When it happens

Trigger: Calling manager.restart(taskId) after manager.shutdown() was invoked or while the process/manager is mid-shutdown (SIGTERM handlers, graceful close, tests tearing down the Mastra instance).

Common situations: A request handler tries to restart a task during server graceful shutdown; an async operation completes after tests shut the manager down and then calls restart.

Related errors


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