{"record":{"id":"4f6fcefc7a5f44d8","repo":"mastra-ai/mastra","slug":"thread-threadid-not-found","errorCode":null,"errorMessage":"Thread ${threadId} not found","messagePattern":"Thread (.+?) not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/memory/src/index.ts","lineNumber":1041,"sourceCode":"      // Use mutex to prevent race conditions when multiple concurrent calls update the same resource/thread\n      const mutexKey = scope === 'resource' ? `resource-${resourceId}` : `thread-${threadId}`;\n      const mutex = this.updateWorkingMemoryMutexes.has(mutexKey)\n        ? this.updateWorkingMemoryMutexes.get(mutexKey)!\n        : new Mutex();\n      this.updateWorkingMemoryMutexes.set(mutexKey, mutex);\n      const release = await mutex.acquire();\n\n      try {\n        const memoryStore = await this.getMemoryStore();\n        if (scope === 'resource' && resourceId) {\n          await memoryStore.updateResource({\n            resourceId,\n            workingMemory,\n          });\n        } else {\n          const thread = await this.getThreadById({ threadId });\n          if (!thread) {\n            throw new Error(`Thread ${threadId} not found`);\n          }\n\n          await memoryStore.patchThread({\n            id: threadId,\n            metadata: {\n              ...thread.metadata,\n              workingMemory,\n            },\n          });\n        }\n      } finally {\n        release();\n      }\n\n      span?.end({ output: { success: true } });\n    } catch (error) {\n      span?.error({ error: error as Error, endSpan: true });\n      throw error;","sourceCodeStart":1023,"sourceCodeEnd":1059,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/memory/src/index.ts#L1023-L1059","documentation":"In thread-scoped working memory updates, the thread must exist because the update patches thread metadata to store working memory. If getThreadById returns null, this error is thrown before patching.","triggerScenarios":"updateWorkingMemory({ threadId, resourceId, workingMemory }) with workingMemory.scope === 'thread' and a threadId that does not exist in storage.","commonSituations":"Calling the update-working-memory tool before the first message creates the thread; DB reset or cleanup removed the thread; stale threadId cached in client state.","solutions":["Create the thread before updating working memory (memory.createThread or let the agent's first message create it)","Verify thread existence with getThreadById before calling updateWorkingMemory","Fix stale/incorrect threadId in application state"],"exampleFix":"// before\nawait memory.updateWorkingMemory({ threadId: newThreadId, resourceId, workingMemory });\n// after\nlet thread = await memory.getThreadById({ threadId: newThreadId });\nif (!thread) {\n  thread = await memory.createThread({ resourceId, title: 'New thread' });\n}\nawait memory.updateWorkingMemory({ threadId: thread.id, resourceId, workingMemory });","handlingStrategy":"validation","validationCode":"const thread = await memory.getThreadById({ threadId });\nif (!thread) await memory.createThread({ resourceId, title: 'Auto-created' });","typeGuard":null,"tryCatchPattern":"try {\n  await memory.updateWorkingMemory({ threadId, resourceId, workingMemory });\n} catch (e) {\n  if (e instanceof Error && e.message.includes('not found')) {\n    // create the thread then retry once\n  } else throw e;\n}","preventionTips":["Ensure a thread exists before any working-memory write","Don't cache threadIds across DB resets","Use upsert-style flows that create the thread on first write"],"tags":["memory","thread","working-memory","not-found"],"backgroundTag":"resource-not-found","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}