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

  1. Configure persistent storage on the Mastra instance (e.g. `new Mastra({ storage: new LibSQLStore(...) })`) if none is set
  2. Capture the runId returned when the run actually suspends (from the suspend event/snapshot), not a client-guessed id
  3. Check the run's status before resuming — if it already completed, start a new run instead
  4. Ensure you don't resume twice; the first resume completes the run and invalidates the snapshot
  5. 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

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


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