mastra-ai/mastra · error · MastraError
DURABLE_AGENT_RECOVER_INVALID_SNAPSHOT
DURABLE_AGENT_RECOVER_INVALID_SNAPSHOT
Error message
DurableAgent "${this.name}" recover(${runId}): persisted snapshot does not contain a durable-agent workflow input. What it means
After loading a persisted run, #loadRecoverableWorkflowInput parses the snapshot and reads snapshot.context.input, requiring it to exist and carry __workflowKind === 'durable-agent'. If the snapshot lacks a durable-agent workflow input, the stored run is not a durable-agent run (or is corrupt), and recover() throws this SYSTEM-category error.
Source
Thrown at packages/core/src/agent/durable/durable-agent.ts:723
if (!persisted) {
throw new MastraError({
id: 'DURABLE_AGENT_RECOVER_SNAPSHOT_NOT_FOUND',
domain: ErrorDomain.AGENT,
category: ErrorCategory.USER,
text:
`DurableAgent "${this.name}" recover(${runId}): no persisted workflow snapshot found. ` +
`The run may have already completed or been cleaned up.`,
details: { agentName: this.name, runId },
});
}
const snapshot =
typeof persisted.snapshot === 'string'
? (JSON.parse(persisted.snapshot) as WorkflowRunState)
: persisted.snapshot;
const workflowInput = snapshot?.context?.input as DurableAgenticWorkflowInput | undefined;
if (!workflowInput || workflowInput.__workflowKind !== 'durable-agent') {
throw new MastraError({
id: 'DURABLE_AGENT_RECOVER_INVALID_SNAPSHOT',
domain: ErrorDomain.AGENT,
category: ErrorCategory.SYSTEM,
text: `DurableAgent "${this.name}" recover(${runId}): persisted snapshot does not contain a durable-agent workflow input.`,
details: { agentName: this.name, runId },
});
}
if (workflowInput.agentId !== this.id) {
throw new MastraError({
id: 'DURABLE_AGENT_RECOVER_AGENT_MISMATCH',
domain: ErrorDomain.AGENT,
category: ErrorCategory.USER,
text: `DurableAgent "${this.name}" recover(${runId}): persisted run belongs to agent "${workflowInput.agentId}", not "${this.id}".`,
details: { agentName: this.name, runId, ownerAgentId: workflowInput.agentId },
});
}
View on GitHub (pinned to 75dd419e61)
Solutions
- Verify the runId refers to a durable-agent run (created by this agent's AGENTIC_LOOP), not a plain workflow run.
- Inspect the persisted snapshot: confirm snapshot.context.input.__workflowKind === 'durable-agent'.
- If the run predates the current schema (version mismatch), re-run the task instead of recovering the old-format run.
- If the snapshot JSON is corrupt, restore from a storage backup or discard the run.
Example fix
// before
await agent.recover(workflowRunId); // actually a plain workflow run
// after
const run = await workflowsStore.getWorkflowRunById({ runId: workflowRunId, workflowName: DurableStepIds.AGENTIC_LOOP });
const snap = typeof run?.snapshot === 'string' ? JSON.parse(run.snapshot) : run?.snapshot;
if (snap?.context?.input?.__workflowKind === 'durable-agent') {
await agent.recover(workflowRunId);
} Defensive patterns
Strategy: type-guard
Validate before calling
const run = await workflowsStore.getWorkflowRunById({ runId, workflowName: DurableStepIds.AGENTIC_LOOP });
const snap = typeof run?.snapshot === 'string' ? JSON.parse(run.snapshot) : run?.snapshot;
const input = snap?.context?.input;
if (input?.__workflowKind !== 'durable-agent') throw new Error(`Run ${runId} is not a durable-agent run.`); Type guard
function isDurableAgentSnapshot(snap: unknown): boolean {
const input = (snap as any)?.context?.input;
return !!input && input.__workflowKind === 'durable-agent';
} Try / catch
try {
await agent.recover(runId);
} catch (e) {
if (String(e?.id) === 'DURABLE_AGENT_RECOVER_INVALID_SNAPSHOT') {
// old-schema or non-durable run: re-run the task instead of recovering
await restartOriginalTask(runId);
} else throw e;
} Prevention
- Only pass runIds produced by the durable-agent AGENTIC_LOOP workflow to recover().
- After Mastra upgrades, validate old snapshots against the current schema before recovering.
- Guard against corrupted snapshots with JSON parse + shape checks before recovery.
When it happens
Trigger: Calling agent.recover(runId) on a run whose snapshot (a) has no context.input, (b) has input without __workflowKind 'durable-agent' — e.g. the runId belongs to a plain workflow run, or the snapshot was written by an older/incompatible version or corrupted (truncated JSON).
Common situations: Passing a regular workflow runId (or another agent's run kind) to recover(); upgrading Mastra where snapshot schema changed and old runs no longer match; corrupted rows from a failed write or manual storage migration.
Related errors
- DURABLE_AGENT_RECOVER_SNAPSHOT_NOT_FOUND
- DURABLE_AGENT_RESUME_INVALID_SNAPSHOT
- DURABLE_AGENT_RECOVER_ALREADY_IN_PROGRESS
- DURABLE_AGENT_RECOVER_LEASE_ACQUIRE_FAILED
- DURABLE_AGENT_RECOVER_AGENT_MISMATCH
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/8bf5b1b5a3c261fe.
Report an issue: GitHub.