Mintplex-Labs/anything-llm · warning

Workspace ${slug} or thread ${threadSlug} is not valid.

Error message

Workspace ${slug} or thread ${threadSlug} is not valid.

What it means

HTTP 400 from POST /api/v1/workspace/:slug/thread/:threadSlug/stream-chat when either the workspace or thread lookup is null, with one message covering both cases. Subtlety: the code calls WorkspaceThread.get({workspace_id: workspace.id}) BEFORE the null check on workspace, so a completely missing workspace usually throws a TypeError ('Cannot read properties of null') that lands in the catch handler instead; this 400 therefore fires most often when the workspace resolves but the thread does not, or when Workspace.get returns undefined.

Source

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

      }
      */
      try {
        const { slug, threadSlug } = request.params;
        const {
          message,
          mode = null,
          userId,
          attachments = [],
          reset = false,
        } = reqBody(request);
        const workspace = await Workspace.get({ slug: String(slug) });
        const thread = await WorkspaceThread.get({
          slug: String(threadSlug),
          workspace_id: workspace.id,
        });

        if (!workspace || !thread) {
          response.status(400).json({
            id: uuidv4(),
            type: "abort",
            textResponse: null,
            sources: [],
            close: true,
            error: `Workspace ${slug} or thread ${threadSlug} is not valid.`,
          });
          return;
        }

        const resolvedMode = mode ?? workspace.chatMode;
        if (
          (!message?.length || !VALID_CHAT_MODE.includes(resolvedMode)) &&
          !reset
        ) {
          response.status(400).json({
            id: uuidv4(),
            type: "abort",

View on GitHub (pinned to 3aec848f28)

Solutions

  1. Check the thread exists under this workspace via the thread chats endpoint first
  2. If the error string appears with a valid workspace, focus on the threadSlug - it is the usual culprit
  3. If the server log shows a TypeError instead, your workspace slug itself is wrong - resolve it via GET /api/v1/workspaces
  4. Create the thread with POST /v1/workspace/:slug/thread/new when missing and use the returned slug

Example fix

// before
await streamThreadChat(slug, threadSlug, message);
// after
const ok = await fetch(`${BASE}/api/v1/workspace/${slug}/thread/${threadSlug}/chats`, { headers: AUTH }).then(r => r.ok);
if (!ok) threadSlug = (await createThread(slug)).slug; // then stream
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) threadSlug = (await createThread(slug)).slug;

Type guard

function isWorkspaceOrThreadInvalid(d) { return d?.type === 'abort' && /is not valid/.test(d.error ?? ''); }

Try / catch

try { await streamThreadChat(slug, threadSlug, body); }
catch (e) { if (isWorkspaceOrThreadInvalid(e.payload)) { await revalidateSlugs(); } else throw e; }

Prevention

When it happens

Trigger: Valid workspace slug with a thread slug that is deleted or belongs to another workspace (400); completely unknown workspace slug often surfaces as the catch path with a TypeError message rather than this 400; sending thread name instead of thread slug.

Common situations: Stale thread references after thread deletion; duplicated workspaces reusing thread slugs; clients assuming thread slugs are global.

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@3aec848f28 (2026-08-18). Data as JSON: /api/errors/11aa4ab2be8e85ed. Report an issue: GitHub.