mastra-ai/mastra · error
Thread ${threadId} not found
Error message
Thread ${threadId} not found What it means
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.
Source
Thrown at packages/memory/src/index.ts:1041
// Use mutex to prevent race conditions when multiple concurrent calls update the same resource/thread
const mutexKey = scope === 'resource' ? `resource-${resourceId}` : `thread-${threadId}`;
const mutex = this.updateWorkingMemoryMutexes.has(mutexKey)
? this.updateWorkingMemoryMutexes.get(mutexKey)!
: new Mutex();
this.updateWorkingMemoryMutexes.set(mutexKey, mutex);
const release = await mutex.acquire();
try {
const memoryStore = await this.getMemoryStore();
if (scope === 'resource' && resourceId) {
await memoryStore.updateResource({
resourceId,
workingMemory,
});
} else {
const thread = await this.getThreadById({ threadId });
if (!thread) {
throw new Error(`Thread ${threadId} not found`);
}
await memoryStore.patchThread({
id: threadId,
metadata: {
...thread.metadata,
workingMemory,
},
});
}
} finally {
release();
}
span?.end({ output: { success: true } });
} catch (error) {
span?.error({ error: error as Error, endSpan: true });
throw error;View on GitHub (pinned to 75dd419e61)
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
Example fix
// before
await memory.updateWorkingMemory({ threadId: newThreadId, resourceId, workingMemory });
// after
let thread = await memory.getThreadById({ threadId: newThreadId });
if (!thread) {
thread = await memory.createThread({ resourceId, title: 'New thread' });
}
await memory.updateWorkingMemory({ threadId: thread.id, resourceId, workingMemory }); Defensive patterns
Strategy: validation
Validate before calling
const thread = await memory.getThreadById({ threadId });
if (!thread) await memory.createThread({ resourceId, title: 'Auto-created' }); Try / catch
try {
await memory.updateWorkingMemory({ threadId, resourceId, workingMemory });
} catch (e) {
if (e instanceof Error && e.message.includes('not found')) {
// create the thread then retry once
} else throw e;
} Prevention
- 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
When it happens
Trigger: updateWorkingMemory({ threadId, resourceId, workingMemory }) with workingMemory.scope === 'thread' and a threadId that does not exist in storage.
Common situations: 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.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- No thread found with id ${threadId}
- thread "${requestedThreadId}" not found
- Received input message with wrong threadId. Input ${message.
- The workingMemory.use option has been removed. Working memor
- WORKING_MEMORY_MISSING_STORAGE_ADAPTER
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/4f6fcefc7a5f44d8.
Report an issue: GitHub.