mastra-ai/mastra · error · Error

Thread ID is required for thread-scoped working memory updat

Error message

Thread ID is required for thread-scoped working memory updates

What it means

The update-working-memory tool was configured with workingMemory.scope = 'thread', meaning memory is scoped per conversation thread, but the tool executed without a threadId in its agent context. Mastra throws this to prevent writing thread-scoped memory without knowing which thread it belongs to. It is a fail-fast guard in the tool's execute function, not a storage failure.

Source

Thrown at packages/memory/src/tools/working-memory.ts:210

    // Strict structured outputs would force every field into `required`, so the model has to
    // emit placeholder values for untouched sections, which then overwrite stored data.
    ...(usesMergeSemantics ? { strict: false as const } : {}),
    execute: async (inputData, context) => {
      const workingMemoryInput = inputData as { memory: any };
      const threadId = context?.agent?.threadId;
      const resourceId = context?.agent?.resourceId;

      // Memory can be accessed via context.memory (when agent is part of Mastra instance)
      // or context.memory (when agent is standalone with memory passed directly)
      const memory = (context as any)?.memory;

      if (!memory) {
        throw new Error('Memory instance is required for working memory updates');
      }

      const scope = memoryConfig?.workingMemory?.scope || 'resource';
      if (scope === 'thread' && !threadId) {
        throw new Error('Thread ID is required for thread-scoped working memory updates');
      }
      if (scope === 'resource' && !resourceId) {
        throw new Error('Resource ID is required for resource-scoped working memory updates');
      }

      if (threadId) {
        let thread = await memory.getThreadById({ threadId });

        if (!thread) {
          thread = await memory.createThread({
            threadId,
            resourceId,
            memoryConfig,
          });
        }

        if (thread.resourceId && resourceId && thread.resourceId !== resourceId) {
          throw new Error(`Thread with id ${threadId} resourceId does not match the current resourceId ${resourceId}`);

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Pass threadId when calling the agent: agent.generate(input, { memory: { thread: threadId, resource: resourceId } }).
  2. Switch workingMemory scope back to 'resource' in the Memory config if per-thread scoping is not actually needed.
  3. Ensure threadId is propagated if the agent runs in a workflow/custom executor that builds its own tool context.
  4. Guard the call site: only run the agent when threadId is present (throw early in your own code).

Example fix

// before
await agent.generate('Save that I like pizza');
// after
await agent.generate('Save that I like pizza', {
  memory: { thread: 'thread-123', resource: 'user-42' },
});
Defensive patterns

Strategy: validation

Validate before calling

if (!threadId) throw new Error('threadId is required before running a thread-scoped-memory agent');

Type guard

const hasThreadId = (v: unknown): v is { threadId: string } =>
  typeof v === 'object' && v !== null && typeof (v as any).threadId === 'string' && (v as any).threadId.length > 0;

Try / catch

try {
  await agent.generate(input, { memory: { thread, resource } });
} catch (e) {
  if (e instanceof Error && e.message.includes('Thread ID is required for thread-scoped')) {
    // fall back to resource scope or re-run with a threadId
  }
}

Prevention

When it happens

Trigger: Calling agent.generate/stream without providing threadId (e.g. memory options omitted) while the agent's memory is configured with workingMemory scope 'thread', so the model invokes the update-working-memory tool and context.agent.threadId is undefined.

Common situations: Migrating from default resource scope to thread scope without updating call sites; calling agent.generate({ messages }) in scripts/tests with no memory: { thread, resource } option; running the agent inside a workflow step that forgets to pass thread context.

Related errors


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