mastra-ai/mastra · error

Execution flow of workflow is not defined. Add steps to the

Error message

Execution flow of workflow is not defined. Add steps to the workflow via .then(), .branch(), etc.

What it means

A workflow run is attempted while `stepFlow` is empty, meaning no execution flow (steps) has been defined. Mastra refuses to start a run with nothing to execute, and throws a plain Error instructing you to compose the workflow with `.then()`, `.branch()`, `.parallel()`, etc.

Source

Thrown at packages/core/src/workflows/workflow.ts:2555

   * @returns A Run instance that can be used to execute the workflow
   */
  async createRun(options?: {
    runId?: string;
    resourceId?: string;
    disableScorers?: boolean;
    /** Optional pubsub instance for streaming events. If not provided, a new EventEmitterPubSub is created. */
    pubsub?: PubSub;
    /**
     * Overrides the workflow-wide `shouldPersistSnapshot` option for this run only.
     * Used for transient runs that must never touch storage even when the workflow
     * persists normally (e.g. per-chunk agent output-processor runs, #19605).
     */
    shouldPersistSnapshot?: WorkflowOptions['shouldPersistSnapshot'];
    /** Overrides the workflow-wide tracing policy for this run only. */
    tracingPolicy?: TracingPolicy;
  }): Promise<Run<TEngineType, TSteps, TState, TInput, TOutput, TRequestContext>> {
    if (this.stepFlow.length === 0) {
      throw new Error(
        'Execution flow of workflow is not defined. Add steps to the workflow via .then(), .branch(), etc.',
      );
    }
    if (!this.executionGraph.steps) {
      throw new Error('Uncommitted step flow changes detected. Call .commit() to register the steps.');
    }
    const runIdToUse =
      options?.runId ||
      this.#mastra?.generateId({
        idType: 'run',
        source: 'workflow',
        entityId: this.id,
        resourceId: options?.resourceId,
      }) ||
      randomUUID();

    // Return a new Run instance with object parameters
    const run =

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Add at least one step: `workflow.then(myStep)` before calling createRun/start.
  2. Review the workflow definition path — ensure the code adding steps actually executes (not behind a false condition).
  3. If the workflow is intentionally empty, don't run it; guard the caller.
  4. Commit the flow after wiring steps (see related Uncommitted-step-flow error).

Example fix

// before
const workflow = new Workflow({ id: 'empty' });
const run = await workflow.createRun();
// after
const workflow = new Workflow({ id: 'w' });
workflow.then(fetchStep).then(processStep).commit();
const run = await workflow.createRun();
Defensive patterns

Strategy: validation

Validate before calling

if (!workflow || (workflow as any).stepFlow?.length === 0) {
  throw new Error('workflow has no steps; add .then()/.branch() before createRun');
}

Type guard

const isRunnable = (w: unknown): w is { createRun: () => unknown } =>
  !!w && typeof w === 'object' && 'createRun' in w && Array.isArray((w as any).stepFlow) && (w as any).stepFlow.length > 0;

Try / catch

try {
  const run = await workflow.createRun();
} catch (e) {
  if (e instanceof Error && e.message.includes('Execution flow of workflow is not defined')) {
    // build the flow programmatically before running
  } else throw e;
}

Prevention

When it happens

Trigger: Calling `workflow.createRun()` or `workflow.start()` on a workflow constructed as `new Workflow({ id, ... })` with no `.then(step)`/`.branch(...)`/`.parallel(...)` calls; steps added only conditionally so the flow ended up empty.

Common situations: Boilerplate workflows created but never wired; conditional assembly where all branch conditions skipped adding steps; refactoring that removed all steps; instantiating a subclass that forgot to define the flow.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/f791ff6985685f00. Report an issue: GitHub.