{"record":{"id":"5857ebe0a19bfaf0","repo":"mastra-ai/mastra","slug":"multiple-suspended-steps-found-pathstrings-join","errorCode":null,"errorMessage":"Multiple suspended steps found: ${pathStrings.join(', ')}. Please specify which step to resume using the \"step\" parameter.","messagePattern":"Multiple suspended steps found: (.+?)\\. Please specify which step to resume using the \"step\" parameter\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/workflows/evented/workflow.ts","lineNumber":2394,"sourceCode":"              suspendedStepPaths.push([stepId, ...nestedPath]);\n            } else {\n              // For single-level suspension, just use the step ID\n              suspendedStepPaths.push([stepId]);\n            }\n          }\n        }\n      });\n\n      if (suspendedStepPaths.length === 0) {\n        throw new Error('No suspended steps found in this workflow run');\n      }\n\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)","sourceCodeStart":2376,"sourceCodeEnd":2412,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/workflows/evented/workflow.ts#L2376-L2412","documentation":"When resuming an evented workflow without an explicit \"step\" parameter, Mastra looks up the snapshot's suspendedPaths. If exactly one step is suspended it auto-selects it; if more than one is suspended it cannot disambiguate, so it throws listing all suspended step paths and asks the caller to pass \"step\". This prevents resuming the wrong branch of the workflow.","triggerScenarios":"Calling workflow.resume({ runId, resumeData }) (or resume with no step) on a run whose snapshot.suspendedPaths contains two or more entries, e.g. after parallel/branch steps both suspended with .suspend().","commonSituations":"Workflows using parallel() or conditionally-exclusive branches where two or more steps call suspend(); developers added a second suspend point after initial testing with only one suspended step; fan-out patterns resuming without a step selector.","solutions":["Pass the step to resume: workflow.resume({ runId, resumeData, step: [stepId] }) (nested steps use the full path array, e.g. step: ['parent', 'child']).","Inspect snapshot.suspendedPaths (via getWorkflowRunState / the error message) to see which paths are suspended and pick the intended one.","If you want auto-resume to work, ensure only one step is suspended per resume (resume sequentially, one branch at a time)."],"exampleFix":"// before\nawait workflow.resume({ runId, resumeData: { approved: true } });\n// after\nawait workflow.resume({ runId, resumeData: { approved: true }, step: ['humanApproval'] });","handlingStrategy":"validation","validationCode":"const snap = await workflow.getWorkflowRunState(runId);\nconst suspended = Object.keys(snap?.suspendedPaths ?? {});\nif (suspended.length > 1) {\n  throw new Error(`Ambiguous resume: pick one of ${suspended.join(', ')}`);\n}\nawait workflow.resume({ runId, resumeData, step: [suspended[0]!] });","typeGuard":null,"tryCatchPattern":"try {\n  await workflow.resume({ runId, resumeData });\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith('Multiple suspended steps found')) {\n    const steps = err.message.match(/\\[(.*?)\\]/g)?.map(s => s.slice(1, -1));\n    await workflow.resume({ runId, resumeData, step: JSON.parse(`[${steps?.[0]}]`) });\n  } else throw err;\n}","preventionTips":["Always pass an explicit step parameter when the workflow has any suspend() inside parallel/branch constructs.","Log snapshot.suspendedPaths before resuming during development.","Resume branches sequentially so only one step is suspended at a time when auto-resume is desired."],"tags":["workflow","resume","ambiguity","suspend"],"backgroundTag":"ambiguous-resume-step","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}