mastra-ai/mastra · error · Error

Memory instance cannot verify thread access for recall

Error message

Memory instance cannot verify thread access for recall

What it means

Thread-access verification in resource-scoped recall requires the Memory instance to implement getThreadById. When the provided memory object lacks this method, Mastra throws rather than skipping the ownership check, because silently skipping would allow cross-resource reads.

Source

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

        throw new Error(
          isResourceScope
            ? 'No active thread context and no cursor or threadId was provided for mode="messages". Pass a threadId (use mode="threads" to discover thread IDs) or a message ID as cursor.'
            : 'No active thread context for mode="messages". This tool is limited to the current thread and no current thread could be resolved.',
        );
      }

      let targetThreadId: string | undefined;
      let threadScope: string | undefined;

      if (!isResourceScope) {
        targetThreadId = currentThreadId;
        threadScope = currentThreadId || undefined;
      } else if (hasResolvedThreadId) {
        if (!resourceId) {
          throw new Error('Resource ID is required for recall');
        }
        if (!memory.getThreadById) {
          throw new Error('Memory instance cannot verify thread access for recall');
        }

        const thread = await memory.getThreadById({ threadId: resolvedThreadId! });
        if (!thread || thread.resourceId !== resourceId) {
          throw new Error('Thread does not belong to the active resource');
        }

        targetThreadId = thread.id;
        threadScope = thread.id;
      } else {
        targetThreadId = currentThreadId;
        threadScope = currentThreadId || undefined;
      }

      if (hasCursor && !hasResolvedThreadId && !currentThreadId) {
        if (!isResourceScope) {
          throw new Error('Current thread is required when browsing by cursor');
        }

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Use a full Mastra Memory instance (or upgrade @mastra/memory to a version that implements getThreadById).
  2. If using a custom storage/memory adapter, implement getThreadById({ threadId }).
  3. Update test mocks to include getThreadById.

Example fix

// before
const memory = { query: async () => ({}) } as any;
// after
import { Memory } from '@mastra/memory';
const memory = new Memory({ storage, options: { ... } });
Defensive patterns

Strategy: type-guard

Type guard

function isFullMemory(m: unknown): m is Memory & { getThreadById: NonNullable<Memory['getThreadById']> } {
  return typeof (m as any)?.getThreadById === 'function';
}

Try / catch

if (!isFullMemory(memoryOrContext)) {
  throw new Error('Provided memory does not implement getThreadById; use a full Memory instance');
}

Prevention

When it happens

Trigger: Passing a custom or partial Memory-like object (e.g. a stub, mock, or older memory class) as context.memory that does not define getThreadById, while mode="messages" resolves an explicit threadId in resource scope.

Common situations: Dependency/version mismatch where the injected memory implementation predates getThreadById; test doubles missing the method; wrapping Memory in a proxy that drops methods.

Related errors


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