{"record":{"id":"01e22d64672b8166","repo":"Mintplex-Labs/anything-llm","slug":"bad-request-01e22d","errorCode":null,"errorMessage":"Bad Request","messagePattern":"Bad Request","errorType":"http","errorClass":null,"httpStatus":400,"severity":"warning","filePath":"server/endpoints/api/workspace/index.js","lineNumber":253,"sourceCode":"    #swagger.parameters['slug'] = {\n        in: 'path',\n        description: 'Unique slug of workspace to delete',\n        required: true,\n        type: 'string'\n    }\n    #swagger.responses[403] = {\n      schema: {\n        \"$ref\": \"#/definitions/InvalidAPIKey\"\n      }\n    }\n    */\n      try {\n        const { slug = \"\" } = request.params;\n        const VectorDb = getVectorDbClass();\n        const workspace = await Workspace.get({ slug: String(slug) });\n\n        if (!workspace) {\n          response.sendStatus(400).end();\n          return;\n        }\n\n        const workspaceId = Number(workspace.id);\n        await WorkspaceChats.delete({ workspaceId: workspaceId });\n        await DocumentVectors.deleteForWorkspace(workspaceId);\n        await Document.delete({ workspaceId: workspaceId });\n        await Workspace.delete({ id: workspaceId });\n\n        await EventLogs.logEvent(\"api_workspace_deleted\", {\n          workspaceName: workspace?.name || \"Unknown Workspace\",\n        });\n        try {\n          await VectorDb[\"delete-namespace\"]({ namespace: slug });\n        } catch (e) {\n          console.error(e.message);\n        }\n        response.sendStatus(200).end();","sourceCodeStart":235,"sourceCodeEnd":271,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/526360e320da9d1b36074be5ed64fe76e5bbfbbd/server/endpoints/api/workspace/index.js#L235-L271","documentation":"Returned by DELETE /v1/workspace/:slug as HTTP 400 when Workspace.get({ slug }) returns null, meaning no workspace exists with the given slug. The handler at server/endpoints/api/workspace/index.js:252 explicitly checks `if (!workspace)` and sends `response.sendStatus(400).end()`. This is a client-side error — the slug in the URL path does not match any workspace in the database. Note this route also passes through the workspaceDeletionProtection middleware which can return 403 if WORKSPACE_DELETION_PROTECTION is set.","triggerScenarios":"DELETE /v1/workspace/non-existent-slug where 'non-existent-slug' has never been created or was already deleted. Also triggered by typos in the slug, URL-encoding issues (spaces or special characters in the slug not properly encoded), or by using the workspace name instead of the slug.","commonSituations":"Attempting to delete a workspace that was already deleted in a previous request. Using the workspace display name (e.g., 'My Workspace') instead of the slug (e.g., 'my-workspace-abc123'). Copy-pasting a slug from the UI that includes trailing whitespace or a trailing slash. Race condition where another admin deleted the workspace between your GET and DELETE.","solutions":["Verify the slug exists first: call GET /v1/workspaces to list all valid slugs.","Ensure you are using the `slug` field (e.g., 'my-workspace'), not the workspace `name` or `id`.","Check for URL-encoding issues: if the slug contains special characters, ensure they are properly percent-encoded.","Strip any trailing slashes or whitespace from the slug in your URL path.","Handle 400 gracefully in your client — it means the resource is already gone, which may be acceptable for a delete operation (treat as idempotent success)."],"exampleFix":"// before — using workspace name instead of slug\nawait fetch('/v1/workspace/My%20Workspace', { method: 'DELETE' });\n\n// after — fetch the correct slug first\nconst { workspaces } = await (await fetch('/v1/workspaces', {\n  headers: { Authorization: `Bearer ${API_KEY}` }\n})).json();\nconst target = workspaces.find(w => w.name === 'My Workspace');\nawait fetch(`/v1/workspace/${target.slug}`, { method: 'DELETE' });","handlingStrategy":"validation","validationCode":"// Verify the workspace slug exists before attempting deletion\nasync function ensureWorkspaceExists(slug, apiKey) {\n  const res = await fetch('/v1/workspaces', {\n    headers: { Authorization: `Bearer ${apiKey}` }\n  });\n  if (!res.ok) throw new Error('Cannot verify workspace list');\n  const { workspaces } = await res.json();\n  return workspaces.some(w => w.slug === slug);\n}","typeGuard":null,"tryCatchPattern":"try {\n  const exists = await ensureWorkspaceExists(slug, API_KEY);\n  if (!exists) {\n    console.log(`Workspace '${slug}' does not exist — treating delete as idempotent success`);\n    return;\n  }\n  const res = await fetch(`/v1/workspace/${slug}`, {\n    method: 'DELETE',\n    headers: { Authorization: `Bearer ${API_KEY}` }\n  });\n  if (res.status === 400) {\n    // Workspace gone — treat as success for idempotent delete\n    return;\n  }\n  if (res.status === 403) throw new Error('Deletion blocked by WORKSPACE_DELETION_PROTECTION');\n} catch (e) { console.error(e); }","preventionTips":["Treat 400 on DELETE as idempotent success — the workspace is already gone.","Always verify the slug via GET /v1/workspaces before deletion to catch typos.","Be aware of the WORKSPACE_DELETION_PROTECTION env var which blocks deletion with 403.","Use the workspace `slug`, never the `name` or `id`, in the URL path."],"tags":["workspace","express","anythingllm","request-validation","not-found"],"backgroundTag":null,"analyzedSha":"526360e320da9d1b36074be5ed64fe76e5bbfbbd","analyzedAt":"2026-08-13T01:45:47.170Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}