DocsReferenceWorkflowsWorkflow

Workflow

The Workflow class enables you to create state machines for complex sequences of operations with conditional branching and data validation.

import { Workflow } from "@mastra/core";
 
const workflow = new Workflow({ name: "my-workflow" });

API Reference

Constructor

name:

string
Identifier for the workflow

logger?:

Logger<WorkflowLogMessage>
Optional logger instance for workflow execution details

steps:

Step[]
Array of steps to include in the workflow

triggerSchema:

z.Schema
Optional schema for validating workflow trigger data

Core Methods

step()

Adds a Step to the workflow, including transitions to other steps. Returns the workflow instance for chaining. Learn more about steps.

commit()

Validates and finalizes the workflow configuration. Must be called after adding all steps.

execute()

Executes the workflow with optional trigger data. Typed based on the trigger schema.

Trigger Schemas

Trigger schemas validate the initial data passed to a workflow using Zod.

const workflow = new Workflow({
  name: "order-process",
  triggerSchema: z.object({
    orderId: z.string(),
    customer: z.object({
      id: z.string(),
      email: z.string().email(),
    }),
  }),
});

The schema:

  • Validates data passed to execute()
  • Provides TypeScript types for your workflow input

Variables & Data Flow

Variables allow steps to access data from:

  • Previous steps’ outputs
  • Trigger data

Variables payloads are typesafe with fields defined in the Step inputSchema.

workflow
  .step("createOrder", {
    // Access trigger data
    variables: {
      orderId: { stepId: "trigger", path: "orderId" },
    },
  })
  .step("processPayment", {
    variables: {
      // Access previous step's data
      orderStatus: { stepId: "createOrder", path: "status" },
      amount: { stepId: "createOrder", path: "total" },
    },
  });

Variable Resolution

  • Variables are resolved in order of step execution
  • Each step can access outputs of all previous steps
  • Paths use dot notation for nested data
  • Missing or invalid paths throw errors during execution

Example

const workflow = new Workflow({
  name: "process-data",
  triggerSchema: z.object({
    items: z.array(
      z.object({
        id: z.number(),
        value: z.number(),
      }),
    ),
  }),
})
  .step("filter", {
    variables: {
      items: { stepId: "trigger", path: "." },
    },
  })
  .step("process", {
    variables: {
      items: { stepId: "filter", path: "filtered.user.name" },
    },
  })
  .commit();

Validation

Workflow validation happens at two key times:

1. At Commit Time

When you call .commit(), the workflow validates:

workflow
  .step('step1', {...})
  .step('step2', {...})
  .commit(); // Validates workflow structure
  • Circular dependencies between steps
  • Terminal paths (every path must end)
  • Unreachable steps
  • Variable references to non-existent steps
  • Duplicate step IDs

2. During Execution

When you call start(), it validates:

const { runId, start } = workflow.createRun();
 
// Validates trigger data against schema
await start({
  triggerData: {
    orderId: "123",
    customer: {
      id: "cust_123",
      email: "invalid-email", // Will fail validation
    },
  },
});
  • Trigger data against trigger schema
  • Each step’s input data against its inputSchema
  • Variable paths exist in referenced step outputs
  • Required variables are present

Error Handling

try {
  const { runId, start } = workflow.createRun();
  await start({ triggerData: data });
} catch (error) {
  if (error instanceof ValidationError) {
    // Handle validation errors
    console.log(error.type); // 'circular_dependency' | 'no_terminal_path' | 'unreachable_step'
    console.log(error.details); // { stepId?: string, path?: string[] }
  }
}

MIT 2025 © Nextra.