Mintplex-Labs/anything-llm · warning
Thread not found
Error message
Thread not found
What it means
HTTP 404 from POST /api/v1/workspace/:slug/thread/:threadSlug/update when no thread matches BOTH slug=threadSlug AND workspace_id=workspace.id. Thread lookup is scoped to the parent workspace, so a thread slug that exists under a different workspace still 404s. The thread slug is the thread's URL identifier, not its name.
Source
Thrown at server/endpoints/api/workspaceThread/index.js:180
"$ref": "#/definitions/InvalidAPIKey"
}
}
*/
try {
const { slug, threadSlug } = request.params;
const { name } = reqBody(request);
const workspace = await Workspace.get({ slug: String(slug) });
if (!workspace) {
response.status(404).json({ message: "Workspace not found" });
return;
}
const thread = await WorkspaceThread.get({
slug: String(threadSlug),
workspace_id: workspace.id,
});
if (!thread) {
response.status(404).json({ message: "Thread not found" });
return;
}
const { thread: updatedThread, message } = await WorkspaceThread.update(
thread,
{ name }
);
response.status(200).json({ thread: updatedThread, message });
} catch (e) {
console.error(e.message, e);
response.sendStatus(500).end();
}
}
);
app.delete(
"/v1/workspace/:slug/thread/:threadSlug",
[validApiKey],View on GitHub (pinned to 3aec848f28)
Solutions
- List the workspace's chats/threads (GET /api/v1/workspace/:slug/threads or thread chats endpoint) to get the current threadSlug
- Confirm the thread belongs to the exact workspace slug in the URL
- If the thread was deleted, create a new one via POST /api/v1/workspace/:slug/thread/new and use the returned slug
- Never guess thread slugs - always persist the slug returned by the create API
Example fix
// before
await updateThread(slug, 'My Thread', { name }); // passing thread NAME
// after
const thread = await findThreadByName(slug, 'My Thread'); // list threads, match on name
await updateThread(slug, thread.slug, { name }); Defensive patterns
Strategy: validation
Validate before calling
const ok = await fetch(`${BASE}/api/v1/workspace/${slug}/thread/${threadSlug}/chats`, { headers: AUTH }).then(r => r.ok);
if (!ok) throw new Error(`thread ${threadSlug} missing under ${slug}`); Type guard
const isThreadRef = (r) => typeof r?.slug === 'string' && typeof r?.workspace_id === 'number' || typeof r?.workspace_id === 'string';
Prevention
- Persist the thread slug returned by thread/new - never construct it
- Remember thread slugs are scoped per workspace
- On 404, re-list threads and rebuild the reference
When it happens
Trigger: Right thread slug under the wrong workspace; thread was deleted from the UI; using the thread's display name or numeric id instead of its slug; stale threadSlug cached by the client after threads were recreated.
Common situations: Duplicating a workspace and reusing thread slugs from the original; client-side autocomplete storing old thread slugs; assuming thread slugs are globally unique when they are only unique per workspace.
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
- Workspace not found
- Workspace ${slug} not found.
- Thread ${threadSlug} not found.
- Workspace ${slug} or thread ${threadSlug} is not valid.
- Message is empty
AI-assisted analysis of Mintplex-Labs/anything-llm@3aec848f28 (2026-08-18).
Data as JSON: /api/errors/f191cb2b9300c710.
Report an issue: GitHub.