mastra-ai/mastra · error

Snapshot not found for runId ${runId}

Error message

Snapshot not found for runId ${runId}

What it means

`updateWorkflowResults` merges a step result into the run's stored snapshot. If the run record exists but has no snapshot (or the snapshot has no `context`), it throws 'Snapshot not found for runId'. The snapshot is the workflow execution state that step results are merged into, so updating results without one is impossible.

Source

Thrown at packages/core/src/storage/domains/workflows/inmemory.ts:224

    if (!run) {
      return {};
    }

    let snapshot: WorkflowRunState;
    if (!run.snapshot) {
      snapshot = createEmptyWorkflowSnapshot(run.run_id);

      this.db.workflows.set(key, {
        ...run,
        snapshot,
      });
    } else {
      snapshot = typeof run.snapshot === 'string' ? JSON.parse(run.snapshot) : run.snapshot;
    }

    if (!snapshot || !snapshot?.context) {
      throw new Error(`Snapshot not found for runId ${runId}`);
    }

    const context = mergeWorkflowStepResult({ snapshot, stepId, result, requestContext });

    this.db.workflows.set(key, {
      ...run,
      snapshot: snapshot,
    });

    return cloneRunData(context);
  }

  async updateWorkflowState({
    workflowName,
    runId,
    opts,
  }: {
    workflowName: string;

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Ensure the workflow run was started and its snapshot persisted (via the run-creation path) before updating results.
  2. Verify the runId passed matches an existing run (fetch the run first and check `snapshot`).
  3. Re-run the workflow if its snapshot was lost; snapshots are not reconstructible after the fact.
  4. If migrating storage, confirm snapshots were carried over in the same format (object or JSON string with `context`).

Example fix

// before
await storage.updateWorkflowResults(runId, 'step-1', { output: 42 }); // run may not have snapshot
// after
const run = await storage.getWorkflowRunById({ runId });
if (run?.snapshot) {
  await storage.updateWorkflowResults(runId, 'step-1', { output: 42 });
}
Defensive patterns

Strategy: try-catch

Validate before calling

async function canUpdateResults(storage, runId: string) {
  const run = await storage.getWorkflowRunById({ runId });
  if (!run) return false;
  const snap = typeof run.snapshot === 'string' ? JSON.parse(run.snapshot) : run.snapshot;
  return Boolean(snap?.context);
}

Type guard

function hasSnapshotContext(run: { snapshot?: unknown } | undefined): boolean {
  if (!run?.snapshot) return false;
  const snap = typeof run.snapshot === 'string' ? safeParse(run.snapshot) : run.snapshot;
  return Boolean((snap as any)?.context);
}

Try / catch

try {
  await storage.updateWorkflowResults(runId, stepId, result, requestContext);
} catch (err) {
  if (err instanceof Error && err.message.startsWith('Snapshot not found for runId')) {
    logger.warn(`No snapshot for run ${runId}; skipping step-result update`);
    return;
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling `updateWorkflowResults(runId, stepId, result, ...)` for a runId whose stored workflow run has no snapshot persisted (never created, cleared, or saved without a `context` object).

Common situations: Writing step results before the run's initial snapshot was persisted, pointing at the wrong runId (typo or stale reference), a run record created by an older version of the library that stored snapshots differently, or external code wiping the snapshot column.

Related errors


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