mastra-ai/mastra · error · Error
This workflow run was not suspended
Error message
This workflow run was not suspended
What it means
resume() only makes sense for runs parked at a suspend point. The snapshot was found in storage but its status is not 'suspended' (e.g. 'running', 'success', 'failed'), so resuming would be meaningless and the library throws.
Source
Thrown at packages/core/src/workflows/evented/workflow.ts:2336
workflowId: this.workflowId,
runId: this.runId,
resourceId: this.resourceId,
},
});
}
const workflowsStore = await this.mastra?.getStorage()?.getStore('workflows');
if (!workflowsStore) {
throw new Error('Cannot resume workflow: workflows store is required');
}
const snapshot = await waitForSuspendedSnapshot(workflowsStore, this.workflowId, this.runId);
if (!snapshot) {
throw new Error(`Cannot resume workflow: no snapshot found for runId ${this.runId}`);
}
// Check if workflow is suspended before proceeding
if (snapshot.status !== 'suspended') {
throw new Error('This workflow run was not suspended');
}
// Resolve label to step path if provided
const snapshotResumeLabel = params.label ? snapshot?.resumeLabels?.[params.label] : undefined;
// Validate label exists if provided
if (params.label && !snapshotResumeLabel) {
const availableLabels = Object.keys(snapshot?.resumeLabels ?? {});
throw new Error(
`Resume label "${params.label}" not found. ` + `Available labels: [${availableLabels.join(', ')}]`,
);
}
// Label takes precedence over step param
const stepParam = snapshotResumeLabel?.stepId ?? params.step;
// Auto-detect suspended steps if no step is provided
let steps: string[];View on GitHub (pinned to 75dd419e61)
Solutions
- Check the run status before resuming and skip if not 'suspended'
- Deduplicate resume calls (idempotency key or in-flight guard)
- Fetch the run's latest snapshot to see the actual status and outcome (success/error) instead of resuming
Example fix
// before
await workflow.resume({ runId, step, resumeData });
// after
const snapshot = await storage.loadWorkflowSnapshot({ workflowId, runId });
if (snapshot?.status === 'suspended') {
await workflow.resume({ runId, step, resumeData });
} Defensive patterns
Strategy: validation
Validate before calling
const snapshot = await storage.loadWorkflowSnapshot({ workflowId, runId });
if (snapshot?.status !== 'suspended') {
throw new Error(`Run is ${snapshot?.status}; only suspended runs can be resumed`);
} Type guard
function isSuspended(s) {
return !!s && s.status === 'suspended';
} Try / catch
try {
await run.resume({ runId, step, resumeData });
} catch (e) {
if (e.message === 'This workflow run was not suspended') {
// treat as idempotent no-op or fetch final result
return getRunResult(runId);
}
throw e;
} Prevention
- Guard resume paths with a status check
- Deduplicate resume triggers (disable UI button after click, idempotency keys)
- Refresh run state before offering resume actions
When it happens
Trigger: Calling resume() on a run whose persisted snapshot.status !== 'suspended' — the run already completed, already failed, is still actively running, or was resumed previously.
Common situations: Double-resume from a retry queue or duplicate event handler; user clicking 'resume' twice in a UI; resuming after the workflow already finished because a watch loop didn't observe completion; stale UI state showing an old suspended run.
Related errors
- This workflow run was not active
- AGENT_RESUME_TOOL_CALL_NOT_SUSPENDED
- Snapshot context not found for runId ${snapshot?.runId}
- Cannot resume workflow: workflows store is required
- Cannot resume workflow: no snapshot found for runId ${this.r
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/aa04e555e535fbd8.
Report an issue: GitHub.