{"record":{"id":"aa5289771e72290a","repo":"Mintplex-Labs/anything-llm","slug":"bad-request-aa5289","errorCode":null,"errorMessage":"Bad Request","messagePattern":"Bad Request","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"server/endpoints/api/workspaceThread/index.js","lineNumber":78,"sourceCode":"                message: null\n              }\n            }\n          }\n        }\n      }\n      #swagger.responses[403] = {\n        schema: {\n          \"$ref\": \"#/definitions/InvalidAPIKey\"\n        }\n      }\n      */\n      try {\n        const wslug = request.params.slug;\n        let { userId = null, name = null, slug = null } = reqBody(request);\n        const workspace = await Workspace.get({ slug: String(wslug) });\n\n        if (!workspace) {\n          response.sendStatus(400).end();\n          return;\n        }\n\n        // If the system is not multi-user and you pass in a userId\n        // it needs to be nullified as no users exist. This can still fail validation\n        // as we don't check if the userID is valid.\n        if (!response.locals.multiUserMode && !!userId) userId = null;\n\n        const { thread, message } = await WorkspaceThread.new(\n          workspace,\n          userId ? Number(userId) : null,\n          { name, slug }\n        );\n\n        await Telemetry.sendTelemetry(\"workspace_thread_created\", {\n          multiUserMode: multiUserMode(response),\n          LLMSelection: process.env.LLM_PROVIDER || \"openai\",\n          Embedder: process.env.EMBEDDING_ENGINE || \"inherit\",","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/f92433b4ea0598492a1e6645ea22addbb4dd1287/server/endpoints/api/workspaceThread/index.js#L60-L96","documentation":"POST /v1/workspace/:slug/thread/new returns 400 when Workspace.get({slug}) resolves to null — the workspace slug in the URL does not exist. The endpoint deliberately maps 'workspace not found' to 400 Bad Request (arguably it should be 404), so 'Bad Request' here means unknown slug, not malformed body. Request body shape ({userId, name, slug}) is not what triggers this.","triggerScenarios":"POSTing to /v1/workspace/my-wrokspace/thread/new with a typo'd or deleted workspace slug; using the workspace name or ID instead of its slug; workspace slug changed via rename; newly created workspace not yet committed when the thread call races ahead.","commonSituations":"Hard-coded slugs in scripts drift after workspaces are renamed or recreated in CI/dev loops; copy-pasting a workspace name where the slug belongs; multi-tenant automation that assumes a workspace exists before it was actually created.","solutions":["GET /v1/workspaces and use the exact 'slug' field of the target workspace in the URL","If the workspace is missing, create it first (POST /v1/workspace/new) and then retry the thread creation","Do not pass the workspace name or numeric id in place of the slug — only the slug resolves"],"exampleFix":"// before\nawait api.post(`/v1/workspace/${name}/thread/new`, { name }); // 400: used display name\n\n// after\nconst { workspaces } = await api.get(\"/v1/workspaces\");\nconst ws = workspaces.find((w) => w.slug === slug);\nif (!ws) throw new Error(`unknown workspace slug: ${slug}`);\nawait api.post(`/v1/workspace/${ws.slug}/thread/new`, { name });","handlingStrategy":"validation","validationCode":"const { workspaces } = await fetch(`${base}/v1/workspaces`, {\n  headers: { Authorization: `Bearer ${apiKey}` },\n}).then((r) => r.json());\nif (!workspaces.some((w) => w.slug === slug))\n  throw new Error(`unknown workspace slug: '${slug}' — create it before opening a thread`);","typeGuard":"/** This endpoint returns 400 for a missing workspace (not 404). */\nfunction isUnknownWorkspace400(res) {\n  return res.status === 400 && !res.headers.get(\"content-length\"); // bare sendStatus(400), empty body\n}","tryCatchPattern":"try {\n  const res = await postThread(slug, body);\n  if (res.status === 400) throw new Error(`workspace slug '${slug}' does not exist`);\n} catch (e) {\n  console.error(\"thread create failed\", e);\n}","preventionTips":["Resolve slugs dynamically from GET /v1/workspaces instead of hard-coding","Create the workspace (POST /v1/workspace/new) and assert success before threading against it","Remember the response is an empty-bodied 400 — don't try to parse a JSON error message"],"tags":["http-400","workspace-thread","workspace-slug","api"],"backgroundTag":"resource-not-found","analyzedSha":"f92433b4ea0598492a1e6645ea22addbb4dd1287","analyzedAt":"2026-08-18T10:02:21.017Z","contentChangedAt":"2026-08-18T10:02:21.017Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}