mastra-ai/mastra · error
Thread 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.
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
- thread " " not found
- Cannot update working memory
- Could not resolve cursor message
- Failed to parse working memory input as JSON
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/4f6fcefc7a5f44d8.
Report an issue: GitHub.
Appendix: 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)