mastra-ai/mastra · error · Error

BackgroundTaskManager is shutting down, cannot initialize

Error message

BackgroundTaskManager is shutting down, cannot initialize

What it means

BackgroundTaskManager.init() refuses to start initialization once shutdown has begun (shuttingDown flag set). This prevents re-subscribing pubsub/workers during or after shutdown, which would leak resources or resurrect a half-torn-down manager. It is a lifecycle-state guard.

Source

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

  __registerMastra(mastra: Mastra) {
    this.#mastra = mastra;
  }

  async getStorage() {
    const storage = this.#mastra?.getStorage();
    if (!storage) {
      throw new Error('Storage is not initialized');
    }
    const bgStore = await storage.getStore('backgroundTasks');
    if (!bgStore) {
      throw new Error('Background tasks storage is not available');
    }
    return bgStore;
  }

  async init(pubsub: PubSub): Promise<void> {
    if (this.shuttingDown) {
      throw new Error('BackgroundTaskManager is shutting down, cannot initialize');
    }
    if (this.initPromise) return this.initPromise;
    this.initPromise = this.#doInit(pubsub);
    return this.initPromise;
  }

  async #doInit(pubsub: PubSub): Promise<void> {
    this.pubsub = pubsub;

    const isProducerOnly = this.config.mode === 'producer';

    // Result listener: fan-out so all processes receive results.
    // Both producer and worker modes need this — the producer uses it
    // to receive completion/failure notifications for dispatched tasks.
    this.resultCallback = async (event: Event, ack?: () => Promise<void>) => {
      if (event.type === 'task.completed' || event.type === 'task.failed') {
        await this.handleResult(event);
      }

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Await init() before initiating shutdown, or skip init if shuttingDown is already true.
  2. Recreate a fresh BackgroundTaskManager instance if you need to run tasks after a shutdown.
  3. Ensure SIGTERM handlers set a flag that gates new init calls, not just enqueue.
  4. Fix test ordering: create a new manager per test instead of re-initializing a shut-down one.

Example fix

// before
await manager.shutdown();
await manager.init(pubsub); // throws
// after
if (!manager.shuttingDown) {
  await manager.init(pubsub);
} // or: manager = new BackgroundTaskManager(...); await manager.init(pubsub);
Defensive patterns

Strategy: validation

Validate before calling

if (manager.shuttingDown) {
  // skip init or create a fresh manager
} else {
  await manager.init(pubsub);
}

Try / catch

try {
  await manager.init(pubsub);
} catch (e) {
  if ((e as Error).message.includes('shutting down, cannot initialize')) {
    manager = new BackgroundTaskManager(...); // fresh instance
    await manager.init(pubsub);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling init() after shutdown()/graceful shutdown started; a fire-and-forget Mastra init racing an explicit shutdown; restarting tasks programmatically during process termination; test teardown ordering where init runs after shutdown.

Common situations: Server SIGTERM handlers calling shutdown while late lazy init fires; hot-reload in dev re-initializing Mastra after shutdown; integration tests that shut down the manager in afterEach while a pending init resolves in the next test.

Related errors


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