mastra-ai/mastra · error · MastraError
AGENT_RESUME_NO_SNAPSHOT_FOUND
AGENT_RESUME_NO_SNAPSHOT_FOUND
Error message
Agent "${this.name}" ${method}() could not find a suspended run for runId "${runId}". ${hasStorage ? `The run may have already completed, never suspended, or the runId is invalid. ` : `No storage is configured on this Mastra instance, so workflow snapshots can't be persisted. Register the agent on a Mastra instance with persistent storage (e.g. PostgreSQL, LibSQL). See https://mastra.ai/docs/storage. `}Ensure you are calling ${method}() only with a runId from a currently-suspended run. What it means
A MastraError (id AGENT_RESUME_NO_SNAPSHOT_FOUND) thrown when `agent.resume()`/`approve()`/`decline()` (method) is called with a runId for which no suspended workflow snapshot ('agentic-loop' workflow) exists in the workflows store. The message distinguishes storage-backed cases (run completed/never suspended/invalid id) from the no-storage case where snapshots can't persist at all.
Source
Thrown at packages/core/src/agent/agent.ts:6728
}
return value;
}
/**
* Loads the agentic-loop workflow snapshot for resume, or throws an actionable error.
* Used by resumeStream and resumeGenerate to fail fast at the agent boundary.
* @internal
*/
async #loadAgenticLoopSnapshotOrThrow({ runId, method }: { runId: string; method: string }) {
const effectiveMastra = this.#mastra ?? (await this.#getOrCreateEphemeralMastra());
const workflowsStore = await effectiveMastra?.getStorage()?.getStore('workflows');
const existingSnapshot = await waitForSuspendedSnapshot(workflowsStore, 'agentic-loop', runId, {
missingSnapshotGraceReads: 3,
});
if (!existingSnapshot) {
const hasStorage = !!workflowsStore;
throw new MastraError({
id: 'AGENT_RESUME_NO_SNAPSHOT_FOUND',
domain: ErrorDomain.AGENT,
category: ErrorCategory.USER,
text:
`Agent "${this.name}" ${method}() could not find a suspended run for runId "${runId}". ` +
(hasStorage
? `The run may have already completed, never suspended, or the runId is invalid. `
: `No storage is configured on this Mastra instance, so workflow snapshots can't be persisted. Register the agent on a Mastra instance with persistent storage (e.g. PostgreSQL, LibSQL). See https://mastra.ai/docs/storage. `) +
`Ensure you are calling ${method}() only with a runId from a currently-suspended run.`,
details: {
runId,
agentName: this.name,
hasStorage,
},
});
}
return existingSnapshot;View on GitHub (pinned to 75dd419e61)
Solutions
- Configure persistent storage on the Mastra instance (e.g. `new Mastra({ storage: new LibSQLStore(...) })`) if none is set
- Capture the runId returned when the run actually suspends (from the suspend event/snapshot), not a client-guessed id
- Check the run's status before resuming — if it already completed, start a new run instead
- Ensure you don't resume twice; the first resume completes the run and invalidates the snapshot
- Verify you're pointing at the same storage backend/environment that recorded the run
Example fix
// before
const mastra = new Mastra({ agents: { myAgent } }); // no storage
// after
const mastra = new Mastra({ agents: { myAgent }, storage: new PostgresStore({ connectionString }) }); Defensive patterns
Strategy: validation
Validate before calling
async function canResume(mastra, agentName, runId) {
if (!mastra.getStorage?.()) throw new Error('configure persistent storage before using suspend/resume');
const run = await mastra.getStorage()?.getWorkflowRunById?.('agentic-loop', runId);
if (!run) throw new Error(`unknown runId ${runId}`);
if (run.status !== 'suspended') throw new Error(`run ${runId} is ${run.status}, not suspended`);
} Type guard
function isSuspendedRun(run) {
return !!run && typeof run === 'object' && run.status === 'suspended' && typeof run.runId === 'string';
} Try / catch
try {
return await agent.resume({ runId });
} catch (e) {
if (e?.id === 'AGENT_RESUME_NO_SNAPSHOT_FOUND') {
logger.warn(`run ${runId} not resumable (completed/invalid/no storage); starting new run`);
return startNewRun();
}
throw e;
} Prevention
- Always configure persistent storage (Postgres/LibSQL) on Mastra when using suspend/resume
- Only resume with runIds captured from the actual suspend event
- Check run status before resume; treat completed runs as terminal
- Persist runIds server-side with the run state, not as long-lived client tokens
When it happens
Trigger: Resuming with a runId that has already completed; resuming a run that never actually suspended; passing an invalid/fabricated runId; calling resume on an agent whose Mastra instance has no persistent storage configured (snapshot never written); racing resume before the suspend snapshot grace-reads (3) complete.
Common situations: Client retries resuming an already-finished run after a timeout; forgetting to configure PostgreSQL/LibSQL storage in dev; copying runIds across environments; resuming from a stale id persisted on the client after the loop ended.
Related errors
- AGENT_RESUME_TOOL_CALL_NOT_SUSPENDED
- AGENT_LIST_SUSPENDED_RUNS_NO_STORAGE
- sendNotificationSignal requires a notifications storage doma
- AGENT_SEND_STREAM_RESUME_NO_SUSPENDED_THREAD_RUN
- No registry entry found for run ${runId}. Cannot resume.
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/87cee5bc25f1ebf2.
Report an issue: GitHub.