{"record":{"id":"88cfa84fa3c1c81b","repo":"mastra-ai/mastra","slug":"could-not-resolve-current-thread","errorCode":null,"errorMessage":"Could not resolve current thread.","messagePattern":"Could not resolve current thread\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/memory/src/tools/om-tools.ts","lineNumber":1373,"sourceCode":"        detail?: RecallDetail;\n        partType?: 'text' | 'tool-call' | 'tool-result' | 'reasoning' | 'image' | 'file';\n        toolName?: string;\n        partIndex?: number;\n        charOffset?: number;\n        before?: string;\n        after?: string;\n      };\n      const memory = (context as any)?.memory as RecallMemory | undefined;\n      const currentThreadId = context?.agent?.threadId;\n      const resourceId = context?.agent?.resourceId;\n      const resolvedExplicitThreadId = explicitThreadId === 'current' ? currentThreadId : explicitThreadId;\n\n      if (!memory) {\n        throw new Error('Memory instance is required for recall');\n      }\n\n      if (explicitThreadId === 'current' && !currentThreadId) {\n        throw new Error('Could not resolve current thread.');\n      }\n\n      // Search mode\n      if (mode === 'search') {\n        // Schema validation rejects mode=\"search\" when search is disabled, but\n        // validation is skipped for resumed runs and builder-validated input —\n        // a stale search call on those paths would otherwise reach\n        // Memory.searchMessages and throw. Return guidance instead.\n        if (!searchEnabled) {\n          return { results: SEARCH_NOT_CONFIGURED_MESSAGE, count: 0 };\n        }\n        if (!query) {\n          throw new Error('query is required for mode=\"search\"');\n        }\n        if (!resourceId) {\n          throw new Error('Resource ID is required for recall');\n        }\n        return searchMessagesForResource({","sourceCodeStart":1355,"sourceCodeEnd":1391,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/memory/src/tools/om-tools.ts#L1355-L1391","documentation":"The recall tool accepts threadId: 'current' as a sentinel meaning \"the thread this run belongs to\" (om-tools.ts:1366, 1372). If the LLM passes 'current' but context.agent.threadId is unset — the run was started without a thread — the sentinel cannot be resolved and the tool throws 'Could not resolve current thread.'","triggerScenarios":"LLM calls the recall tool with threadId='current' (or resource-scope mode where threadId defaults to current) during an agent run launched without a threadId parameter, so context.agent.threadId is undefined.","commonSituations":"Stateless one-off agent.generate/stream calls with no threadId; interactive UIs that forgot to create/attach a thread per user; memory threads pruned between turns; tests invoking the agent without thread scaffolding.","solutions":["Always start memory-backed conversations with a threadId: agent.generate({ messages, resourceId, threadId }).","If no thread exists, pass a concrete threadId (or call mode='threads' after creating one) instead of 'current'.","Have the client/UI create a thread up front via memory.createThread and reuse its ID.","Catch this error in tooling and return guidance telling the model a thread must be created first."],"exampleFix":"// before\nawait agent.generate({ messages, resourceId }); // no threadId\n// after\nawait agent.generate({ messages, resourceId, threadId: thread.id });","handlingStrategy":"validation","validationCode":"// before relying on threadId: 'current'\nif (explicitThreadId === 'current' && !context?.agent?.threadId) {\n  throw new Error(\"threadId='current' requested but the run has no thread\");\n}","typeGuard":"function canResolveCurrentThread(\n  ctx?: { agent?: { threadId?: string } }\n): ctx is { agent: { threadId: string } } {\n  return typeof ctx?.agent?.threadId === 'string' && ctx.agent.threadId.length > 0;\n}","tryCatchPattern":"try {\n  return await recallExecute(inputData, context);\n} catch (err) {\n  if (err instanceof Error && err.message === 'Could not resolve current thread.') {\n    return { error: 'No current thread — start a conversation with a threadId first.' };\n  }\n  throw err;\n}","preventionTips":["Always pass threadId to agent.generate/stream when memory is enabled.","Reserve the 'current' sentinel for runs you know are thread-bound.","Catch this in tool middleware and instruct the model to create a thread instead."],"tags":["memory","thread-id","tool-context","sentinel-value"],"backgroundTag":"missing-required-parameter","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}