{"record":{"id":"29a5b3298bef176e","repo":"mastra-ai/mastra","slug":"thread-id-is-required-for-thread-scoped-working-me","errorCode":null,"errorMessage":"Thread ID is required for thread-scoped working memory updates","messagePattern":"Thread ID is required for thread-scoped working memory updates","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/memory/mock.ts","lineNumber":263,"sourceCode":"      updateWorkingMemory: createTool({\n        id: 'update-working-memory',\n        description,\n        inputSchema: z.object({ memory: z.string() }),\n        execute: async (inputData, context) => {\n          const threadId = context?.agent?.threadId;\n          const resourceId = context?.agent?.resourceId;\n\n          // Memory can be accessed via context.memory (when agent is part of Mastra instance)\n          // or context.memory (when agent is standalone with memory passed directly)\n          const memory = (context as any)?.memory;\n\n          if (!memory) {\n            throw new Error('Memory instance is required for working memory updates');\n          }\n\n          const scope = mergedConfig.workingMemory?.scope || 'resource';\n          if (scope === 'thread' && !threadId) {\n            throw new Error('Thread ID is required for thread-scoped working memory updates');\n          }\n          if (scope === 'resource' && !resourceId) {\n            throw new Error('Resource ID is required for resource-scoped working memory updates');\n          }\n\n          if (threadId) {\n            let thread = await memory.getThreadById({ threadId });\n\n            if (!thread) {\n              thread = await memory.createThread({\n                threadId,\n                resourceId,\n                memoryConfig: _config,\n              });\n            }\n\n            if (thread.resourceId && resourceId && thread.resourceId !== resourceId) {\n              throw new Error(","sourceCodeStart":245,"sourceCodeEnd":281,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/memory/mock.ts#L245-L281","documentation":"When working memory scope is 'thread', updates must target a specific conversation thread. The working-memory tool in listTools validates that a threadId is present in the context and throws a plain Error when it is missing, because a thread-scoped write without a thread has no destination.","triggerScenarios":"Running an agent whose merged workingMemory config has `scope: 'thread'` while the generate/stream call (or tool invocation) lacks a threadId in the memory request context.","commonSituations":"Forgetting to pass `threadId` (e.g. `agent.generate(msg, { memory: { thread: '...' } })` omitted or misnamed); switching scope from default 'resource' to 'thread' without updating call sites; direct tool invocation without thread context.","solutions":["Always supply a threadId in the memory options of the agent call: `{ memory: { thread: 'thread-123', resource: 'user-1' } }`.","If threads are not used, change workingMemory scope to 'resource' and ensure resourceId is provided.","When invoking the tool directly in tests, include threadId in the context."],"exampleFix":"// before\nawait agent.generate('save my prefs', { memory: { resource: 'user-1' } }); // scope: 'thread'\n// after\nawait agent.generate('save my prefs', {\n  memory: { thread: 'thread-123', resource: 'user-1' },\n});","handlingStrategy":"validation","validationCode":"const scope = memoryConfig?.workingMemory?.scope ?? 'resource';\nif (scope === 'thread' && !threadId) throw new Error('threadId is required for thread-scoped working memory');\nif (scope === 'resource' && !resourceId) throw new Error('resourceId is required for resource-scoped working memory');","typeGuard":"function hasThreadId(ctx: unknown): ctx is { threadId: string } {\n  return typeof (ctx as any)?.threadId === 'string' && (ctx as any).threadId.length > 0;\n}","tryCatchPattern":"try {\n  await agent.generate(input, memoryOpts);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('Thread ID is required')) {\n    // retry with an explicit thread id or switch workingMemory scope to 'resource'\n  } else throw e;\n}","preventionTips":["Always pass both thread and resource in agent memory options when scope is 'thread'.","Default scope is 'resource' — only switch to 'thread' after updating call sites.","Generate thread IDs deterministically per conversation so they are never omitted."],"tags":["memory","working-memory","thread-id","validation"],"backgroundTag":"missing-thread-id","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}