mastra-ai/mastra · error

Uncommitted step flow changes detected. Call .commit() to re

Error message

Uncommitted step flow changes detected. Call .commit() to register the steps.

What it means

Steps were added to the workflow (stepFlow is non-empty) but the resulting execution graph was not committed, so `executionGraph.steps` is missing. Mastra requires an explicit `.commit()` to freeze the step flow into an execution graph before any run can start.

Source

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

    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 =
      this.#runs.get(runIdToUse) ??
      new Run({
        workflowId: this.id,
        stateSchema: this.stateSchema,
        inputSchema: this.inputSchema,

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Call `.commit()` on the workflow after wiring all steps, before createRun/start.
  2. If steps were appended after an earlier commit, re-commit.
  3. Call commit once during module initialization right after the flow is fully defined.
  4. Check any wrapper/factory that builds workflows returns them only after commit.

Example fix

// before
workflow.then(a).then(b);
const run = await workflow.createRun();
// after
workflow.then(a).then(b).commit();
const run = await workflow.createRun();
Defensive patterns

Strategy: validation

Validate before calling

if ((workflow as any).stepFlow?.length && !(workflow as any).executionGraph?.steps) {
  throw new Error('call workflow.commit() before createRun/start');
}

Type guard

const isCommitted = (w: unknown): boolean =>
  !!w && typeof w === 'object' && !!(w as any).executionGraph?.steps;

Try / catch

try {
  const run = await workflow.createRun();
} catch (e) {
  if (e instanceof Error && e.message.includes('Uncommitted step flow changes')) {
    (workflow as any).commit?.();
    // retry createRun
  } else throw e;
}

Prevention

When it happens

Trigger: Calling createRun()/start() after `.then()`/`.branch()`/`.parallel()` calls without invoking `.commit()`; adding more steps after commit and re-running without committing again.

Common situations: New users unaware Mastra requires commit; dynamically appending steps at runtime then re-running; old code upgraded to versions enforcing commit.

Related errors


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