mastra-ai/mastra · error

recall requires a Memory instance with storage access

Error message

recall requires a Memory instance with storage access

What it means

recallMessages() needs more than any object that resembles memory — it explicitly checks typeof memory.getMemoryStore === 'function' to prove the instance exposes storage-backed methods (getMemoryStore, recall, getThreadById). Passing a duck-typed stub, a plain config object, or a different class (e.g. a store rather than a Memory) fails this duck-type check and throws.

Source

Thrown at packages/memory/src/tools/om-tools.ts:927

  cursor: string;
  page?: number;
  limit?: number;
  detail?: RecallDetail;
  partType?: 'text' | 'tool-call' | 'tool-result' | 'reasoning' | 'image' | 'file';
  toolName?: string;
  threadScope?: string;
  maxTokens?: number;
}): Promise<RecallResult> {
  if (!memory) {
    throw new Error('Memory instance is required for recall');
  }

  if (!threadId) {
    throw new Error('Thread ID is required for recall');
  }

  if (typeof memory.getMemoryStore !== 'function') {
    throw new Error('recall requires a Memory instance with storage access');
  }

  const MAX_PAGE = 50;
  const MAX_LIMIT = 20;
  const rawPage = page === 0 ? 1 : page;
  const normalizedPage = Math.max(Math.min(rawPage, MAX_PAGE), -MAX_PAGE);
  const normalizedLimit = Math.min(limit, MAX_LIMIT);

  const resolved = await resolveCursorMessage(memory, cursor, {
    resourceId,
    threadScope,
    enforceThreadScope: false,
  });

  if ('hint' in resolved) {
    return {
      messages: resolved.hint,
      count: 0,

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Pass a real Memory instance: new Memory({ storage, options }) from @mastra/memory, not a config object or storage instance.
  2. If memory crossed a serialization boundary, reconstruct it with new Memory(config) on the consuming side.
  3. Update mocks in tests to implement getMemoryStore (and recall/getThreadById) as functions.
  4. Check @mastra/core and @mastra/memory versions align so the expected method exists.

Example fix

// before
await recallMessages({ memory: { ...memoryConfig }, threadId, cursor });
// after
import { Memory } from '@mastra/memory';
const memory = new Memory({ storage });
await recallMessages({ memory, threadId, cursor });
Defensive patterns

Strategy: type-guard

Validate before calling

// before calling recallMessages
if (typeof (memory as any)?.getMemoryStore !== 'function') {
  throw new Error('Pass a Memory instance (new Memory(...)), not a config object or storage');
}

Type guard

function isStorageBackedMemory(m: unknown): m is RecallMemory {
  return (
    !!m &&
    typeof m === 'object' &&
    typeof (m as any).getMemoryStore === 'function' &&
    typeof (m as any).recall === 'function'
  );
}

Try / catch

try {
  return await recallMessages({ memory, threadId, cursor });
} catch (err) {
  if (err instanceof Error && err.message.includes('storage access')) {
    memory = new Memory(memoryConfig); // rebuild from config
    return await recallMessages({ memory, threadId, cursor });
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling recallMessages({ memory: <store or mock or wrong object>, threadId, cursor }) where memory exists and threadId is set, but the object lacks a getMemoryStore method — e.g. passing a MastraStorage instance, a serialized/parsed Memory copy (methods lost through JSON), or a hand-rolled mock.

Common situations: Persisting a Memory instance via JSON (class methods dropped on revival); passing the memory *config* object instead of a `new Memory(config)` instance; mocking Memory in tests with only `recall` stubbed; importing Memory from mismatched package versions where the method was renamed.

Understand the failure class

Background: "Wrong argument type", "must be a string", "expected Array or Prism::Scope": TypeError and ArgumentError when a library receives a value of the wrong type — this error's family across 28 libraries.

Related errors


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