Mintplex-Labs/anything-llm · error
Internal Server Error
Error message
Internal Server Error
What it means
Returned by POST /v1/workspace/new when an exception occurs after the Workspace.new call succeeds but before the response is sent, or when Workspace.new itself throws. The handler at server/endpoints/api/system index catches errors from Workspace.new (Prisma create), Telemetry.sendTelemetry (network call to telemetry endpoint), and EventLogs.logEvent (Prisma create). A subtle issue: if Workspace.new succeeds but Telemetry.sendTelemetry throws, the workspace IS created but the client sees a 500 — a silent partial-success state.
Source
Thrown at server/endpoints/api/workspace/index.js:105
response.status(400).json({ workspace: null, message });
return;
}
await Telemetry.sendTelemetry("workspace_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",
LLMModel: getModelTag(),
});
await EventLogs.logEvent("api_workspace_created", {
workspaceName: workspace?.name || "Unknown Workspace",
});
response.status(200).json({ workspace, message });
} catch (e) {
console.error(e.message, e);
response.sendStatus(500).end();
}
});
app.get("/v1/workspaces", [validApiKey], async (request, response) => {
/*
#swagger.tags = ['Workspaces']
#swagger.description = 'List all current workspaces'
#swagger.responses[200] = {
content: {
"application/json": {
schema: {
type: 'object',
example: {
workspaces: [
{
"id": 79,
"name": "Sample workspace",
"slug": "sample-workspace",View on GitHub (pinned to 526360e320)
Solutions
- Check server logs to identify whether Workspace.new, Telemetry.sendTelemetry, or EventLogs.logEvent threw — the stack trace will show which.
- If telemetry is the culprit, set DISABLE_TELEMETRY or the relevant env var to disable telemetry calls (check Telemetry model for the flag).
- Verify the request body: ensure `name` is a non-empty string and any additionalFields match expected types (openAiTemp as number, etc.).
- After a 500, check if the workspace was actually created via GET /v1/workspaces — it may exist as a partial-success artifact.
- Ensure the database is reachable and the workspaces table schema matches the Prisma schema.
Example fix
// before — telemetry endpoint unreachable causes 500 even on success // (no env var set) // after — disable telemetry if your environment blocks outbound calls // In .env: // DISABLE_TELEMETRY_EVENTS=true
Defensive patterns
Strategy: try-catch
Validate before calling
// Validate workspace creation body before sending
function validateNewWorkspaceBody(body) {
if (!body.name || typeof body.name !== 'string')
return { valid: false, error: 'name is required and must be a string' };
if (body.openAiTemp != null && typeof body.openAiTemp !== 'number')
return { valid: false, error: 'openAiTemp must be a number' };
if (body.openAiHistory != null && typeof body.openAiHistory !== 'number')
return { valid: false, error: 'openAiHistory must be a number' };
return { valid: true };
} Try / catch
try {
const res = await fetch('/v1/workspace/new', {
method: 'POST',
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${API_KEY}` },
body: JSON.stringify({ name: 'My Workspace' })
});
if (res.status === 500) {
// CRITICAL: workspace may have been created before telemetry threw.
// Verify via list endpoint
const { workspaces } = await (await fetch('/v1/workspaces', {
headers: { Authorization: `Bearer ${API_KEY}` }
})).json();
const created = workspaces.find(w => w.name === 'My Workspace');
if (created) return created; // partial success — workspace exists
throw new Error('Workspace creation failed entirely');
}
return await res.json();
} catch (e) { console.error(e); } Prevention
- After a 500 on workspace creation, always verify via GET /v1/workspaces whether the workspace was partially created.
- Disable telemetry in air-gapped/firewalled environments to prevent telemetry-throws from masking successful operations.
- Send only the `name` field for basic workspace creation — omit optional fields unless needed.
- Ensure all optional fields have the correct JS type (numbers for numeric fields).
When it happens
Trigger: POST /v1/workspace/new with a name that violates a DB constraint (e.g., null name when the DB column is NOT NULL without a default). Also when Telemetry.sendTelemetry throws due to network restrictions (firewall blocking the telemetry endpoint) or when EventLogs.logEvent fails (DB issue). If the Prisma `workspaces` table has a unique constraint on slug and the auto-generated slug collides, Workspace.new throws.
Common situations: Air-gapped or firewall-restricted deployments where the telemetry endpoint is unreachable, causing sendTelemetry to throw even though workspace creation succeeded. Database connection issues. Sending unexpected field types in additionalFields that Prisma rejects (e.g., a string where a number is expected for openAiTemp).
Understand the failure class
- HTTP status errors: handling 4xx and 5xx responses — how to handle 4xx and 5xx responses properly.
Related errors
AI-assisted analysis of Mintplex-Labs/anything-llm@526360e320 (2026-08-13).
Data as JSON: /api/errors/719cc46c8e8dfb58.
Report an issue: GitHub.