workflow resume on workflow as step not working

Or I should say, it's not working using the client JS even though it does appear to work in the playground. But we're stuck not understanding what the difference is. Here is our workflow:
const turnWorkflow = createWorkflow({
id: "turn",
stateSchema,
inputSchema: emptySchema,
outputSchema: advocateOutputSchema,
})
.then(gatherStep)
.then(advocateStep)
.commit();

export const supportSessionWorkflow = createWorkflow({
id: "support-session",
description:
"Multi-turn human-in-the-loop support session using suspend/resume.",
stateSchema,
inputSchema: intakeInputSchema,
outputSchema: finalizeOutputSchema,
})
.then(intakeStep)
.dountil(
turnWorkflow,
async ({ state: { status } }) =>
status === "resolved" || status === "not_possible"
)
.then(finalStep)
.commit();
const turnWorkflow = createWorkflow({
id: "turn",
stateSchema,
inputSchema: emptySchema,
outputSchema: advocateOutputSchema,
})
.then(gatherStep)
.then(advocateStep)
.commit();

export const supportSessionWorkflow = createWorkflow({
id: "support-session",
description:
"Multi-turn human-in-the-loop support session using suspend/resume.",
stateSchema,
inputSchema: intakeInputSchema,
outputSchema: finalizeOutputSchema,
})
.then(intakeStep)
.dountil(
turnWorkflow,
async ({ state: { status } }) =>
status === "resolved" || status === "not_possible"
)
.then(finalStep)
.commit();
gatherStep is the suspended step and when using the client :
const stream = await runRef.current.resumeStreamVNext({
step: stepId,
resumeData,
});
const stream = await runRef.current.resumeStreamVNext({
step: stepId,
resumeData,
});
Even when resumeData is passed in correctly, it always ends up undefined in the step. This is working for steps which are NOT workflows like the above and we are not able to see why.
5 Replies
flippyhead
flippyheadOP4d ago
And in the browser console I have a step that DOES include the resumeData:
{
"type": "workflow-step-start",
"runId": "84bd10e2-d53d-4098-9de0-8074574b7b9b",
"from": "WORKFLOW",
"payload": {
"stepName": "turn",
"id": "turn",
"stepCallId": "5e0082c1-8573-4543-8213-50382459c140",
"payload": {
"status": "pending",
"responseToUser": "Thank you for providing the details. I'll reach out to the restaurant's support team to request a refund for the duplicate $500 charge. I'll keep you updated on any responses or further actions needed.",
"responseToThirdParty": "DRAFT MESSAGE TO RESTAURANT SUPPORT:\n\nSubject: Request for Refund of Duplicate Charge\n\nDear [Restaurant Support Team],\n\nI am writing on behalf of a customer who was double charged on their recent bill at your restaurant. The duplicate charge amounts to $500.\n\nWe kindly request a refund for this duplicate charge. Please let us know the next steps to resolve this issue promptly.\n\nThank you for your attention to this matter.\n\nBest regards,\n\n[Your Name]\nConsumer Advocate",
"awaiting": "third_party"
},
"startedAt": 1760699890484,
"status": "running",
"metadata": {
"iterationCount": 2
},
"suspendPayload": {
"suspendResponse": "More information from the THIRD-PARTY is needed.",
"awaiting": "third_party",
"__workflow_meta": {
"runId": "84bd10e2-d53d-4098-9de0-8074574b7b9b",
"path": [
"gather"
]
}
},
"suspendedAt": 1760699890489,
"resumePayload": {
"message": "OK",
"source": "third_party",
"sentAt": "2025-10-17T11:18:13.274Z"
},
"resumedAt": 1760699893295
}
}
{
"type": "workflow-step-start",
"runId": "84bd10e2-d53d-4098-9de0-8074574b7b9b",
"from": "WORKFLOW",
"payload": {
"stepName": "turn",
"id": "turn",
"stepCallId": "5e0082c1-8573-4543-8213-50382459c140",
"payload": {
"status": "pending",
"responseToUser": "Thank you for providing the details. I'll reach out to the restaurant's support team to request a refund for the duplicate $500 charge. I'll keep you updated on any responses or further actions needed.",
"responseToThirdParty": "DRAFT MESSAGE TO RESTAURANT SUPPORT:\n\nSubject: Request for Refund of Duplicate Charge\n\nDear [Restaurant Support Team],\n\nI am writing on behalf of a customer who was double charged on their recent bill at your restaurant. The duplicate charge amounts to $500.\n\nWe kindly request a refund for this duplicate charge. Please let us know the next steps to resolve this issue promptly.\n\nThank you for your attention to this matter.\n\nBest regards,\n\n[Your Name]\nConsumer Advocate",
"awaiting": "third_party"
},
"startedAt": 1760699890484,
"status": "running",
"metadata": {
"iterationCount": 2
},
"suspendPayload": {
"suspendResponse": "More information from the THIRD-PARTY is needed.",
"awaiting": "third_party",
"__workflow_meta": {
"runId": "84bd10e2-d53d-4098-9de0-8074574b7b9b",
"path": [
"gather"
]
}
},
"suspendedAt": 1760699890489,
"resumePayload": {
"message": "OK",
"source": "third_party",
"sentAt": "2025-10-17T11:18:13.274Z"
},
"resumedAt": 1760699893295
}
}
But somehow that's not making it to the step within the sub-workflow.
flippyhead
flippyheadOP4d ago
GitHub
[BUG] Resuming a suspended step runs the workflow from the first st...
Describe the Bug No matter how I resume a workflow, whether I pass the step name or a step instance in the step property, the workflow always starts from the beginning and provides resumeData to th...
flippyhead
flippyheadOP4d ago
This is a pretty old issue, but I'm not sure -- was this ever resolved? So just to clarify:
The Problem │ │
│ │ │ │
│ │ 1. Your gather step is inside a turnWorkflow which is inside a doUntil loop │ │
│ │ 2. When suspended, Mastra marks the parent "turn" workflow as suspended, not │ │
│ │ "gather" directly │ │
│ │ 3. The resumeData IS being sent (we see it in the stream events as resumePayload) │ │
│ │ 4. But it's not reaching the gather step's resumeData parameter (showing as │ │
│ │ undefined)
The Problem │ │
│ │ │ │
│ │ 1. Your gather step is inside a turnWorkflow which is inside a doUntil loop │ │
│ │ 2. When suspended, Mastra marks the parent "turn" workflow as suspended, not │ │
│ │ "gather" directly │ │
│ │ 3. The resumeData IS being sent (we see it in the stream events as resumePayload) │ │
│ │ 4. But it's not reaching the gather step's resumeData parameter (showing as │ │
│ │ undefined)
Mastra Triager
GitHub
[DISCORD:1428704762848870462] workflow resume on workflow as step n...
This issue was created from Discord post: https://discord.com/channels/1309558646228779139/1428704762848870462 Or I should say, it's not working using the client JS even though it does appear t...
rase-
rase-14h ago
@flippyhead I believe the issue is that you need to pass the whole resume path: [stepId, nestedWorkflowStepId] instead of just the path to the nested workflow that was resumed. Alternatively, if it's the only step that is currently suspended, you can resume without passing the step property in which case it will figure it out for you. The whole path to what has been suspended should be recorded on result.suspended of the workflow execution result. Let me know if this helps

Did you find this page helpful?