Skip to main content
Mastra v1 is coming in January 2026. Get ahead by starting new projects with the beta or upgrade your existing project today.

Workflow.while()

The .while() method repeats a step as long as a specified condition remains true. This creates a loop that continues executing the specified step until the condition becomes false.

UsageDirect link to Usage

workflow.step(incrementStep).while(condition, incrementStep).then(finalStep);

ParametersDirect link to Parameters

condition:

Function | ReferenceCondition
A function or reference condition that determines when to continue looping

step:

Step
The step to repeat while the condition is true

Condition TypesDirect link to Condition Types

Function ConditionDirect link to Function Condition

You can use a function that returns a boolean:

workflow
.step(incrementStep)
.while(async ({ context }) => {
const result = context.getStepResult<{ value: number }>("increment");
return (result?.value ?? 0) < 10; // Continue as long as value is less than 10
}, incrementStep)
.then(finalStep);

Reference ConditionDirect link to Reference Condition

You can use a reference-based condition with comparison operators:

workflow
.step(incrementStep)
.while(
{
ref: { step: incrementStep, path: "value" },
query: { $lt: 10 }, // Continue as long as value is less than 10
},
incrementStep,
)
.then(finalStep);

Comparison OperatorsDirect link to Comparison Operators

When using reference-based conditions, you can use these comparison operators:

OperatorDescriptionExample
$eqEqual to{ $eq: 10 }
$neNot equal to{ $ne: 0 }
$gtGreater than{ $gt: 5 }
$gteGreater than or equal to{ $gte: 10 }
$ltLess than{ $lt: 20 }
$lteLess than or equal to{ $lte: 15 }

ReturnsDirect link to Returns

workflow:

LegacyWorkflow
The workflow instance for chaining

ExampleDirect link to Example

import { LegacyWorkflow, LegacyStep } from "@mastra/core/workflows/legacy";
import { z } from "zod";

// Create a step that increments a counter
const incrementStep = new LegacyStep({
id: "increment",
description: "Increments the counter by 1",
outputSchema: z.object({
value: z.number(),
}),
execute: async ({ context }) => {
// Get current value from previous execution or start at 0
const currentValue =
context.getStepResult<{ value: number }>("increment")?.value ||
context.getStepResult<{ startValue: number }>("trigger")?.startValue ||
0;

// Increment the value
const value = currentValue + 1;
console.log(`Incrementing to ${value}`);

return { value };
},
});

// Create a final step
const finalStep = new LegacyStep({
id: "final",
description: "Final step after loop completes",
execute: async ({ context }) => {
const finalValue = context.getStepResult<{ value: number }>(
"increment",
)?.value;
console.log(`Loop completed with final value: ${finalValue}`);
return { finalValue };
},
});

// Create the workflow
const counterWorkflow = new LegacyWorkflow({
name: "counter-workflow",
triggerSchema: z.object({
startValue: z.number(),
targetValue: z.number(),
}),
});

// Configure the workflow with a while loop
counterWorkflow
.step(incrementStep)
.while(async ({ context }) => {
const targetValue = context.triggerData.targetValue;
const currentValue =
context.getStepResult<{ value: number }>("increment")?.value ?? 0;
return currentValue < targetValue;
}, incrementStep)
.then(finalStep)
.commit();

// Execute the workflow
const run = counterWorkflow.createRun();
const result = await run.start({
triggerData: { startValue: 0, targetValue: 5 },
});
// Will increment from 0 to 4, then stop and execute finalStep