{"record":{"id":"b89d3d68bc2cb0a1","repo":"mastra-ai/mastra","slug":"this-workflow-run-was-not-suspended","errorCode":null,"errorMessage":"This workflow run was not suspended","messagePattern":"This workflow run was not suspended","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/agent/durable/durable-agent.ts","lineNumber":1950,"sourceCode":"      // A persisted durable run can outlive this process (or the registry TTL).\n      // Rebuild the non-serializable runtime state before resuming the stored\n      // workflow snapshot. Keep warm resumes on the existing path to avoid\n      // racing an active registry entry with a second preparation pass.\n      const workflowsStore = await this.#mastra?.getStorage()?.getStore('workflows');\n      const persisted = await workflowsStore?.getWorkflowRunById({\n        runId,\n        workflowName: DurableStepIds.AGENTIC_LOOP,\n      });\n      if (!persisted) {\n        throw new Error(`No registry entry found for run ${runId}. Cannot resume.`);\n      }\n\n      const snapshot =\n        typeof persisted.snapshot === 'string'\n          ? (JSON.parse(persisted.snapshot) as WorkflowRunState)\n          : persisted.snapshot;\n      if (snapshot?.status !== 'suspended') {\n        throw new Error('This workflow run was not suspended');\n      }\n      const workflowInput = snapshot?.context?.input as DurableAgenticWorkflowInput | undefined;\n      if (!workflowInput || workflowInput.__workflowKind !== 'durable-agent') {\n        throw new MastraError({\n          id: 'DURABLE_AGENT_RESUME_INVALID_SNAPSHOT',\n          domain: ErrorDomain.AGENT,\n          category: ErrorCategory.SYSTEM,\n          text: `DurableAgent \"${this.name}\" resume(${runId}): persisted snapshot does not contain a durable-agent workflow input.`,\n          details: { agentName: this.name, runId },\n        });\n      }\n      if (workflowInput.agentId !== this.id) {\n        throw new MastraError({\n          id: 'DURABLE_AGENT_RESUME_AGENT_MISMATCH',\n          domain: ErrorDomain.AGENT,\n          category: ErrorCategory.USER,\n          text: `DurableAgent \"${this.name}\" resume(${runId}): persisted run belongs to agent \"${workflowInput.agentId}\", not \"${this.id}\".`,\n          details: { agentName: this.name, runId, ownerAgentId: workflowInput.agentId },","sourceCodeStart":1932,"sourceCodeEnd":1968,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/agent/durable/durable-agent.ts#L1932-L1968","documentation":"DurableAgent resume only supports runs whose persisted workflow snapshot has status 'suspended'. If the stored snapshot shows the run is running, completed, failed, or in another state, resuming is meaningless and this Error is thrown from durable-agent.ts:1950.","triggerScenarios":"Calling resume(runId, data) on a run that already completed or failed; calling resume concurrently while the workflow is actively executing; resuming a run that was never suspended at the human-in-the-loop step; calling resume twice with the same resumeData (second call sees a running/completed run).","commonSituations":"Double-submitting a resume from a UI button without disabling it; a background job already resumed the run before the user interaction; retry logic firing after the run reached terminal state; resuming after a crash where the run actually kept going.","solutions":["Fetch the persisted run state (workflows store getWorkflowRunById) and only call resume when status === 'suspended'.","If the run already completed, read its result instead of resuming.","Deduplicate resume calls (disable the UI action / idempotency key) so only one resume is issued per suspension.","If the run is stuck in 'running' after a crash, use recover() instead of resume()."],"exampleFix":"// before\nawait agent.resume(runId, data);\n// after\nconst run = await mastra.getStorage()?.getStore('workflows')?.getWorkflowRunById({ runId, workflowName: 'agentic-loop' });\nconst status = typeof run?.snapshot === 'string' ? JSON.parse(run.snapshot).status : run?.snapshot?.status;\nif (status === 'suspended') await agent.resume(runId, data);","handlingStrategy":"validation","validationCode":"const run = await mastra.getStorage()?.getStore('workflows')?.getWorkflowRunById({ runId, workflowName: 'agentic-loop' });\nconst snap = typeof run?.snapshot === 'string' ? JSON.parse(run.snapshot) : run?.snapshot;\nif (snap?.status !== 'suspended') return; // skip resume","typeGuard":"function isSuspended(snapshot: unknown): snapshot is { status: 'suspended' } {\n  return typeof snapshot === 'object' && snapshot !== null && (snapshot as any).status === 'suspended';\n}","tryCatchPattern":"try {\n  await agent.resume(runId, data);\n} catch (e) {\n  if (String(e) === 'This workflow run was not suspended') {\n    // already running/finished: fetch result or ignore duplicate resume\n  } else throw e;\n}","preventionTips":["Check run status before resuming (idempotent resume guard).","Disable resume UI while a resume request is in flight.","Use a single owner/job to issue resumes per run."],"tags":["durable-agent","resume","workflow-state"],"backgroundTag":"workflow-not-suspended","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}