{"record":{"id":"9714e0e926be00c6","repo":"mastra-ai/mastra","slug":"backgroundtaskmanager-is-shutting-down-cannot-res","errorCode":null,"errorMessage":"BackgroundTaskManager is shutting down, cannot resume tasks","messagePattern":"BackgroundTaskManager is shutting down, cannot resume tasks","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/background-tasks/manager.ts","lineNumber":414,"sourceCode":"          runId: taskId,\n        });\n      }\n      return;\n    }\n  }\n\n  /**\n   * Resume a suspended task. The tool executor must be re-registered via\n   * `registerTaskContext(taskId, ...)` before calling this if the original\n   * registration is gone (e.g. process restart) — the manager doesn't\n   * rehydrate executor closures from storage.\n   *\n   * `resumeData` is forwarded to the tool's `execute` options on the\n   * resumed run.\n   */\n  async resume(taskId: string, resumeData?: unknown): Promise<BackgroundTask> {\n    if (this.shuttingDown) {\n      throw new Error('BackgroundTaskManager is shutting down, cannot resume tasks');\n    }\n    if (!this.#mastra) {\n      throw new Error('Mastra is not registered with this manager');\n    }\n\n    if (this.initPromise) await this.initPromise;\n\n    const storage = await this.getStorage();\n    const task = await storage.getTask(taskId);\n    if (!task) {\n      throw new Error(`Task not found: ${taskId}`);\n    }\n    if (task.status !== 'suspended') {\n      throw new Error(`Cannot resume task in status '${task.status}' (expected 'suspended')`);\n    }\n\n    const canRun = await this.checkConcurrency(task.agentId);\n    if (!canRun) {","sourceCodeStart":396,"sourceCodeEnd":432,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/background-tasks/manager.ts#L396-L432","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Defer resume until after restart: check manager.shuttingDown and persist resumeData for post-restart replay.","Perform shutdown drain first: resume/complete suspended tasks, then call shutdown().","Re-create the manager (new process/instance) and resume there once shuttingDown is false.","Gate auto-resume handlers on the shutdown flag."],"exampleFix":"// before\nawait manager.resume(taskId, data); // may throw during shutdown\n// after\nif (manager.shuttingDown) {\n  await saveForRestart(taskId, data); // replay after restart\n} else {\n  await manager.resume(taskId, data);\n}","handlingStrategy":"validation","validationCode":"if (manager.shuttingDown) {\n  await saveForRestart(taskId, resumeData);\n  return;\n}","typeGuard":null,"tryCatchPattern":"try {\n  await manager.resume(taskId, data);\n} catch (e) {\n  if ((e as Error).message.includes('shutting down, cannot resume')) {\n    await persistResumeIntent(taskId, data); // replay after restart\n    return;\n  }\n  throw e;\n}","preventionTips":["Drain suspended tasks before calling shutdown().","Check shuttingDown before auto-resume paths fire.","Persist resume intents for post-restart replay.","Avoid retry loops against a shutting-down manager."],"tags":["background-tasks","shutdown","resume"],"backgroundTag":"manager-already-shutting-down","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}