Mintplex-Labs/anything-llm · error

Internal Server Error

Error message

Internal Server Error

What it means

Returned by POST /v1/workspace/:slug/thread/new when WorkspaceThread.new, Telemetry.sendTelemetry, or EventLogs.logEvent throws after the workspace is successfully found. The handler at server/endpoints/api/workspaceThread/index.js:104 catches errors from the thread creation pipeline. WorkspaceThread.new creates a Prisma record in the workspace_threads table — it can fail on DB constraints (duplicate slug if a custom thread slug collides with an existing one). As with error 585, if Telemetry.sendTelemetry throws after the thread is created, the thread exists in the DB but the client sees a 500 — a silent partial-success state.

Source

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

          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",
          VectorDbSelection: process.env.VECTOR_DB || "lancedb",
          TTSSelection: process.env.TTS_PROVIDER || "native",
        });
        await EventLogs.logEvent("api_workspace_thread_created", {
          workspaceName: workspace?.name || "Unknown Workspace",
        });
        response.status(200).json({ thread, message });
      } catch (e) {
        console.error(e.message, e);
        response.sendStatus(500).end();
      }
    }
  );

  app.post(
    "/v1/workspace/:slug/thread/:threadSlug/update",
    [validApiKey],
    async (request, response) => {
      /*
      #swagger.tags = ['Workspace Threads']
      #swagger.description = 'Update thread name by its unique slug.'
      #swagger.parameters['slug'] = {
          in: 'path',
          description: 'Unique slug of workspace',
          required: true,
          type: 'string'
      }
      #swagger.parameters['threadSlug'] = {

View on GitHub (pinned to 526360e320)

Solutions

  1. Check server logs to determine whether WorkspaceThread.new, Telemetry.sendTelemetry, or EventLogs.logEvent threw.
  2. If providing a custom thread `slug` in the body, ensure it is unique within the workspace.
  3. If providing a `userId`, ensure it references a valid user (in multi-user mode): GET /v1/users to verify.
  4. After a 500, check if the thread was actually created via GET /v1/workspace/:slug — it may exist as a partial-success artifact.
  5. If telemetry is the culprit, disable telemetry events if your environment blocks outbound network calls.
  6. Omit the body `slug` to let WorkspaceThread.new auto-generate a unique slug.

Example fix

// before — custom slug that may collide
await fetch('/v1/workspace/my-ws/thread/new', {
  method: 'POST',
  body: JSON.stringify({ slug: 'my-thread', userId: 999 })
});

// after — let the system generate the slug, verify userId exists
await fetch('/v1/workspace/my-ws/thread/new', {
  method: 'POST',
  body: JSON.stringify({ name: 'My Thread' })
});
Defensive patterns

Strategy: validation

Validate before calling

// Validate thread creation body and verify workspace/user exist
async function validateThreadCreation(slug, body, apiKey) {
  const wsRes = await fetch('/v1/workspaces', { headers: { Authorization: `Bearer ${apiKey}` } });
  const { workspaces } = await wsRes.json();
  if (!workspaces.some(w => w.slug === slug))
    return { valid: false, error: 'Workspace not found' };
  if (body.slug) {
    // Custom slugs risk collision — warn the caller
    console.warn('Custom thread slug provided — ensure it is unique within the workspace');
  }
  if (body.userId != null && typeof body.userId !== 'number')
    return { valid: false, error: 'userId must be a number' };
  return { valid: true };
}

Try / catch

try {
  const check = await validateThreadCreation(slug, body, API_KEY);
  if (!check.valid) throw new Error(check.error);
  const res = await fetch(`/v1/workspace/${slug}/thread/new`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${API_KEY}` },
    body: JSON.stringify(body)
  });
  if (res.status === 500) {
    // CRITICAL: thread may have been created before telemetry threw.
    // Verify via workspace thread listing
    throw new Error('Thread creation may have partially succeeded — verify via GET endpoint');
  }
  return await res.json();
} catch (e) { console.error(e); }

Prevention

When it happens

Trigger: POST /v1/workspace/valid-slug/thread/new with a body `slug` value that already exists for a thread in the same workspace (unique constraint violation). Also when userId references a non-existent user (the code passes userId to WorkspaceThread.new which creates the thread with a foreign key to users — if the user does not exist, the FK constraint fires). When Telemetry.sendTelemetry throws due to network restrictions. When EventLogs.logEvent fails (DB issue). In single-user mode, passing a userId is nullified (line 85), but in multi-user mode an invalid userId is passed through.

Common situations: Air-gapped deployments where telemetry is blocked, causing the thread to be created but the response to be 500. Passing a custom thread slug that duplicates an existing thread slug in the same workspace. Passing a userId that was deleted or never existed (FK violation). Database connection issues during the Prisma create.

Understand the failure class

Related errors


AI-assisted analysis of Mintplex-Labs/anything-llm@526360e320 (2026-08-13). Data as JSON: /api/errors/56774cb6902fb902. Report an issue: GitHub.