mastra-ai/mastra · error · MastraError

DURABLE_AGENT_RECOVER_SNAPSHOT_NOT_FOUND

DURABLE_AGENT_RECOVER_SNAPSHOT_NOT_FOUND

Error message

DurableAgent "${this.name}" recover(${runId}): no persisted workflow snapshot found. The run may have already completed or been cleaned up.

What it means

#loadRecoverableWorkflowInput reads the persisted workflow run from the workflows store via getWorkflowRunById({ runId, workflowName: DurableStepIds.AGENTIC_LOOP }). If no persisted record exists, there is no snapshot to rebuild the durable workflow input from, so recover() throws this USER error. It means the runId has nothing recoverable behind it.

Source

Thrown at packages/core/src/agent/durable/durable-agent.ts:706

            ?.getLogger?.()
            ?.warn?.(`[DurableAgent] recover(${runId}) failed to release recovery lease: ${error}`);
        } finally {
          if (localRecoveryClaims.get(key) === owner) localRecoveryClaims.delete(key);
        }
      },
    };
  }

  async #loadRecoverableWorkflowInput(
    workflowsStore: WorkflowsStorage,
    runId: string,
  ): Promise<DurableAgenticWorkflowInput> {
    const persisted = await workflowsStore.getWorkflowRunById({
      runId,
      workflowName: DurableStepIds.AGENTIC_LOOP,
    });
    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',

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Confirm the runId exists in the workflows store (query the run by ID before recovering).
  2. Verify the agent's workflowsStore points at the same storage that persisted the original run (env/config check).
  3. If the run completed or was cleaned up, re-run the original task instead of recovering.
  4. Recover within your retention window; extend snapshot retention if legitimate runs are being purged.

Example fix

// before
await agent.recover(runId); // runId from last month, snapshot purged
// after
const persisted = await workflowsStore.getWorkflowRunById({ runId, workflowName: DurableStepIds.AGENTIC_LOOP });
if (!persisted) {
  console.warn(`Run ${runId} not recoverable; restarting task`);
  await restartTask();
} else {
  await agent.recover(runId);
}
Defensive patterns

Strategy: validation

Validate before calling

const persisted = await workflowsStore.getWorkflowRunById({ runId, workflowName: DurableStepIds.AGENTIC_LOOP });
if (!persisted) throw new Error(`Run ${runId} has no persisted snapshot; cannot recover.`);

Try / catch

try {
  await agent.recover(runId);
} catch (e) {
  if (String(e?.id) === 'DURABLE_AGENT_RECOVER_SNAPSHOT_NOT_FOUND') {
    await restartOriginalTask(runId); // snapshot gone; re-execute instead
  } else throw e;
}

Prevention

When it happens

Trigger: Calling agent.recover(runId) when the workflows store has no run record for that runId under the AGENTIC_LOOP workflow — the run never started, already completed and was cleaned up, or the runId is wrong/typo'd.

Common situations: Recovering runs after a storage cleanup/retention job removed old snapshots; typo'd or stale runId from an old environment; pointing at a different storage backend than the one that recorded the run (dev DB vs prod DB).

Related errors


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