{"record":{"id":"6b7d3120b346081d","repo":"mastra-ai/mastra","slug":"this-workflow-step-steps-0-was-not-suspend","errorCode":null,"errorMessage":"This workflow step \"${steps?.[0]}\" was not suspended. Available suspended steps: [${suspendedStepIds.join(', ')}]","messagePattern":"This workflow step \"(.+?)\" was not suspended\\. Available suspended steps: \\[(.+?)\\]","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/workflows/evented/workflow.ts","lineNumber":2406,"sourceCode":"\n      if (suspendedStepPaths.length === 1) {\n        // For single suspended step, use the full path\n        steps = suspendedStepPaths[0]!;\n      } else {\n        const pathStrings = suspendedStepPaths.map(path => `[${path.join(', ')}]`);\n        throw new Error(\n          `Multiple suspended steps found: ${pathStrings.join(', ')}. ` +\n            'Please specify which step to resume using the \"step\" parameter.',\n        );\n      }\n    }\n\n    // Validate that the step is actually suspended\n    const suspendedStepIds = Object.keys(snapshot?.suspendedPaths ?? {});\n    const isStepSuspended = suspendedStepIds.includes(steps?.[0] ?? '');\n\n    if (!isStepSuspended) {\n      throw new Error(\n        `This workflow step \"${steps?.[0]}\" was not suspended. Available suspended steps: [${suspendedStepIds.join(', ')}]`,\n      );\n    }\n\n    const resumePath = snapshot.suspendedPaths?.[steps[0]!] as any;\n    // Start with the snapshot's request context (old values)\n    const requestContextObj = snapshot.requestContext ?? {};\n    const requestContext = new RequestContext();\n\n    // First, set values from the snapshot\n    for (const [key, value] of Object.entries(requestContextObj)) {\n      requestContext.set(key, value);\n    }\n\n    // Then, override with any values from the passed request context (new values take precedence)\n    if (params.requestContext) {\n      for (const [key, value] of params.requestContext.entries()) {\n        requestContext.set(key, value);","sourceCodeStart":2388,"sourceCodeEnd":2424,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/workflows/evented/workflow.ts#L2388-L2424","documentation":"Mastra validates that the step named in resume's \"step\" parameter is actually in the snapshot's suspendedPaths before resuming. If the named step was not suspended (or already resumed/completed), it throws listing which steps ARE currently suspended so the caller can correct the request.","triggerScenarios":"workflow.resume({ runId, step: 'myStep' }) where myStep is not among Object.keys(snapshot.suspendedPaths) — the step never suspends, already resumed, or the name/step path is wrong (e.g. missing parent for nested steps).","commonSituations":"Typos in step IDs; resuming a step twice (second call fails); resuming after the workflow failed or finished; passing a top-level step name when the suspended step is nested inside a parallel/block (needs full path array).","solutions":["Use a step name/path exactly as listed in the error's \"Available suspended steps\" (nested steps use the path array, e.g. step: ['parallel', 'innerStep']).","Check the run snapshot first: const snap = await workflow.getWorkflowRunState(runId); confirm Object.keys(snap.suspendedPaths).","Guard against double-resume in application code (track resumed runs) since a step is no longer suspended after it resumes."],"exampleFix":"// before\nawait workflow.resume({ runId, resumeData, step: 'approveStep' }); // typo\n// after\nawait workflow.resume({ runId, resumeData, step: ['approval', 'approveStep'] });","handlingStrategy":"validation","validationCode":"const snap = await workflow.getWorkflowRunState(runId);\nconst suspended = Object.keys(snap?.suspendedPaths ?? {});\nif (!suspended.includes(stepId)) {\n  throw new Error(`${stepId} is not suspended; suspended: ${suspended.join(', ')}`);\n}\nawait workflow.resume({ runId, resumeData, step: [stepId] });","typeGuard":null,"tryCatchPattern":"try {\n  await workflow.resume({ runId, resumeData, step: [stepId] });\n} catch (err) {\n  if (err instanceof Error && err.message.includes('was not suspended')) {\n    // refresh snapshot and resume whichever step is actually suspended\n    const snap = await workflow.getWorkflowRunState(runId);\n    const available = Object.keys(snap?.suspendedPaths ?? {});\n    if (available.length) await workflow.resume({ runId, resumeData, step: available as any });\n  } else throw err;\n}","preventionTips":["Copy step IDs from the workflow definition rather than retyping them.","Track which runs have already been resumed to avoid double-resume.","For nested steps, always pass the full path array including parent step IDs."],"tags":["workflow","resume","suspend","validation"],"backgroundTag":"step-not-suspended","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}