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
- Pass threadId when calling the agent: agent.generate(input, { memory: { thread: threadId, resource: resourceId } }).
- Switch workingMemory scope back to 'resource' in the Memory config if per-thread scoping is not actually needed.
- Ensure threadId is propagated if the agent runs in a workflow/custom executor that builds its own tool context.
- 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
- Always pass memory: { thread, resource } together when calling generate/stream.
- Type the memory options object so threadId is required, not optional, in your app's helper wrapper.
- Keep scope config and call sites in sync; document scope choice near the Memory constructor.
- Add an integration test that runs the agent with thread-scoped memory.
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
- Resource ID is required for resource-scoped working memory u
- WORKING_MEMORY_MISSING_STORAGE_ADAPTER
- Resource ID is required for resource-scoped working memory u
- Cannot update working memory: ${scope} ID is required
- Working memory is not enabled for this memory instance
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/514b3f6fda08b999.
Report an issue: GitHub.