Mintplex-Labs/anything-llm · error

Bad Request

Error message

Bad Request

What it means

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.

Solutions

  1. GET /v1/workspaces and use the exact 'slug' field of the target workspace in the URL
  2. If the workspace is missing, create it first (POST /v1/workspace/new) and then retry the thread creation
  3. Do not pass the workspace name or numeric id in place of the slug — only the slug resolves

Example fix

// before
await api.post(`/v1/workspace/${name}/thread/new`, { name }); // 400: used display name

// after
const { workspaces } = await api.get("/v1/workspaces");
const ws = workspaces.find((w) => w.slug === slug);
if (!ws) throw new Error(`unknown workspace slug: ${slug}`);
await api.post(`/v1/workspace/${ws.slug}/thread/new`, { name });
Defensive patterns

Strategy: validation

Validate before calling

const { workspaces } = await fetch(`${base}/v1/workspaces`, {
  headers: { Authorization: `Bearer ${apiKey}` },
}).then((r) => r.json());
if (!workspaces.some((w) => w.slug === slug))
  throw new Error(`unknown workspace slug: '${slug}' — create it before opening a thread`);

Type guard

/** This endpoint returns 400 for a missing workspace (not 404). */
function isUnknownWorkspace400(res) {
  return res.status === 400 && !res.headers.get("content-length"); // bare sendStatus(400), empty body
}

Try / catch

try {
  const res = await postThread(slug, body);
  if (res.status === 400) throw new Error(`workspace slug '${slug}' does not exist`);
} catch (e) {
  console.error("thread create failed", e);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

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


AI-assisted analysis of Mintplex-Labs/anything-llm@f92433b4ea (2026-08-18). Data as JSON: /api/errors/aa5289771e72290a. Report an issue: GitHub.

Appendix: source

Thrown at server/endpoints/api/workspaceThread/index.js:78

                message: null
              }
            }
          }
        }
      }
      #swagger.responses[403] = {
        schema: {
          "$ref": "#/definitions/InvalidAPIKey"
        }
      }
      */
      try {
        const wslug = request.params.slug;
        let { userId = null, name = null, slug = null } = reqBody(request);
        const workspace = await Workspace.get({ slug: String(wslug) });

        if (!workspace) {
          response.sendStatus(400).end();
          return;
        }

        // If the system is not multi-user and you pass in a userId
        // it needs to be nullified as no users exist. This can still fail validation
        // as we don't check if the userID is valid.
        if (!response.locals.multiUserMode && !!userId) userId = null;

        const { thread, message } = await WorkspaceThread.new(
          workspace,
          userId ? Number(userId) : null,
          { name, slug }
        );

        await Telemetry.sendTelemetry("workspace_thread_created", {
          multiUserMode: multiUserMode(response),
          LLMSelection: process.env.LLM_PROVIDER || "openai",
          Embedder: process.env.EMBEDDING_ENGINE || "inherit",

View on GitHub (pinned to f92433b4ea)