mastra-ai/mastra · error

This workflow run was not suspended

Error message

This workflow run was not suspended

What it means

Thrown by _resume() when the snapshot exists but its status is not 'suspended' — the run is in some other lifecycle state (running, completed, failed) and cannot be resumed.

Source

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

          resourceId: this.resourceId,
        },
        metadata: {
          workflowId: this.workflowId,
          runId: this.runId,
          resourceId: this.resourceId,
        },
      });
    }

    const workflowsStore = await this.#mastra?.getStorage()?.getStore('workflows');
    const snapshot = await waitForSuspendedSnapshot(workflowsStore, this.workflowId, this.runId);

    if (!snapshot) {
      throw new Error('No snapshot found for this workflow run: ' + this.workflowId + ' ' + this.runId);
    }

    if (snapshot.status !== 'suspended') {
      throw new Error('This workflow run was not suspended');
    }

    const snapshotResumeLabel = params.label ? snapshot?.resumeLabels?.[params.label] : undefined;
    const stepParam = snapshotResumeLabel?.stepId ?? params.step;

    // Auto-detect suspended steps if no step is provided
    let steps: string[];
    if (stepParam) {
      let newStepParam = stepParam;
      if (typeof stepParam === 'string') {
        newStepParam = stepParam.split('.');
      }
      steps = (Array.isArray(newStepParam) ? newStepParam : [newStepParam]).map(step =>
        typeof step === 'string' ? step : step?.id,
      );
    } else {
      // Use suspendedPaths to detect suspended steps
      const suspendedStepPaths: string[][] = [];

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Load the run state first and only call resume() when status === 'suspended'.
  2. For failed runs, use error handling/retry or restart(), not resume().
  3. Update UI state after transitions so stale resume buttons are disabled.
  4. Wait for the workflow to actually reach the suspend point (e.g. use the returned promise or watch status) before resuming.

Example fix

// before
await run.resume({ resumeData, step: 'approve' });
// after
const snapshot = await run.getWorkflowRunState();
if (snapshot.status === 'suspended') {
  await run.resume({ resumeData, step: 'approve' });
}
Defensive patterns

Strategy: validation

Validate before calling

const snapshot = await run.getWorkflowRunState();
if (snapshot.status !== 'suspended') {
  throw new Error(`Cannot resume: run status is ${snapshot.status}`);
}

Type guard

function isSuspended(s: { status?: string }): boolean {
  return s.status === 'suspended';
}

Try / catch

try {
  await run.resume({ resumeData, step });
} catch (e) {
  if (e instanceof Error && e.message === 'This workflow run was not suspended') {
    // refresh UI state; skip resume or restart for failed runs
  } else throw e;
}

Prevention

When it happens

Trigger: Calling resume() on a run that already completed or failed; resuming after another caller already resumed it (status 'running'); calling resume() before the workflow actually reached the suspend point (race after start()).

Common situations: Double resume after a webhook fires twice; resuming from a stale UI state; workflow finished while user had the resume page open; attempting resume on a failed run that needs a restart() instead.

Related errors


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