mastra-ai/mastra · error
Thread not found: ${threadId}
Error message
Thread not found: ${threadId} What it means
After loading the thread from storage, cloneToCurrentResource validates it exists, belongs to expectedResourceId, carries the expected projectPath metadata, and is NOT already owned by the current resource. If any check fails the library reports 'Thread not found' rather than leaking the real reason (wrong owner, foreign project, or already-current), keeping thread ids unscoped.
Source
Thrown at packages/core/src/agent-controller/session.ts:445
threadId,
expectedResourceId,
expectedProjectPath,
}: {
threadId: string;
expectedResourceId: string;
expectedProjectPath: string;
}): Promise<AgentControllerThread> {
if (!this.#store?.hasStorage()) {
throw new Error('Memory is not configured on this AgentController');
}
const thread = await this.#store.getById({ threadId });
if (
!thread ||
thread.resourceId !== expectedResourceId ||
thread.metadata?.projectPath !== expectedProjectPath ||
expectedResourceId === this.#getResourceId()
) {
throw new Error(`Thread not found: ${threadId}`);
}
return this.#cloneThread({
sourceThreadId: thread.id,
resourceId: this.#getResourceId(),
title: thread.title,
metadata: thread.metadata,
});
}
/**
* Load a thread and verify it belongs to this session's resourceId before
* allowing access. Threads owned by another resource are treated as missing
* so a session can never read, switch to, rename, or delete a thread it does
* not own (the thread id is otherwise an unguessable but unscoped key). Throws
* `Thread not found: <id>` when the thread is absent or owned by someone else.
*/
async #requireOwnedThread({ threadId }: { threadId: string }): Promise<AgentControllerThread> {
const thread = await this.#store?.getById({ threadId });View on GitHub (pinned to 75dd419e61)
Solutions
- Verify the threadId exists in storage and matches the expected resourceId and metadata.projectPath before calling.
- Call listThreads/lookup first and skip cloning when the thread is already owned by the current resource.
- Handle the throw as 'not cloneable for this resource' in UI and offer thread creation instead.
Example fix
// before
await session.cloneToCurrentResource({ threadId: someId, expectedResourceId: 'a', expectedProjectPath: '/p' });
// after
const thread = await store.getById({ threadId: someId });
if (thread && thread.resourceId === 'a' && thread.metadata?.projectPath === '/p') {
await session.cloneToCurrentResource({ threadId: someId, expectedResourceId: 'a', expectedProjectPath: '/p' });
} Defensive patterns
Strategy: validation
Validate before calling
const thread = await store.getById({ threadId });
const cloneable = !!thread && thread.resourceId === expectedResourceId && thread.metadata?.projectPath === expectedProjectPath;
if (!cloneable) throw new Error('Thread is not cloneable into this resource'); Try / catch
try {
await session.cloneToCurrentResource(args);
} catch (e) {
if (e instanceof Error && e.message.startsWith('Thread not found: ')) {
// treat as not-found/not-permitted; refresh thread list
} else throw e;
} Prevention
- Only pass threadIds obtained from listing the same resource's threads
- Skip clone when the thread is already the current one
- Keep metadata.projectPath in sync with the actual project
- Refresh UI thread lists after deletions
When it happens
Trigger: Calling cloneToCurrentResource with a threadId that was deleted, belongs to a different resourceId, lacks metadata.projectPath, or is already owned by the current resource (expectedResourceId === current resource).
Common situations: Stale UI references to a deleted thread; copying a thread-id from another user/project; re-invoking clone on the thread already active in this session.
Related errors
- No active thread on this session
- No source thread to clone
- tool_result must be preceded by a tool_call
- Factory session does not belong to this project
- Could not create the session. Reload the page and try again.
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/fcb295fb34f09dde.
Report an issue: GitHub.