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 (Legacy) with Cyclical dependencies

Workflows support cyclical dependencies where steps can loop back based on conditions. The example below shows how to use conditional logic to create loops and handle repeated execution.

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

async function main() {
const doubleValue = new LegacyStep({
id: "doubleValue",
description: "Doubles the input value",
inputSchema: z.object({
inputValue: z.number(),
}),
outputSchema: z.object({
doubledValue: z.number(),
}),
execute: async ({ context }) => {
const doubledValue = context.inputValue * 2;
return { doubledValue };
},
});

const incrementByOne = new LegacyStep({
id: "incrementByOne",
description: "Adds 1 to the input value",
outputSchema: z.object({
incrementedValue: z.number(),
}),
execute: async ({ context }) => {
const valueToIncrement = context?.getStepResult<{ firstValue: number }>(
"trigger",
)?.firstValue;
if (!valueToIncrement) throw new Error("No value to increment provided");
const incrementedValue = valueToIncrement + 1;
return { incrementedValue };
},
});

const cyclicalWorkflow = new LegacyWorkflow({
name: "cyclical-workflow",
triggerSchema: z.object({
firstValue: z.number(),
}),
});

cyclicalWorkflow
.step(doubleValue, {
variables: {
inputValue: {
step: "trigger",
path: "firstValue",
},
},
})
.then(incrementByOne)
.after(doubleValue)
.step(doubleValue, {
variables: {
inputValue: {
step: doubleValue,
path: "doubledValue",
},
},
})
.commit();

const { runId, start } = cyclicalWorkflow.createRun();

console.log("Run", runId);

const res = await start({ triggerData: { firstValue: 6 } });

console.log(res.results);
}

main();





View source on GitHub

Workflows (Legacy)Direct link to Workflows (Legacy)

The following links provide example documentation for legacy workflows:

On this page