Mintplex-Labs/anything-llm · error

Internal Server Error

Error message

Internal Server Error

What it means

The generic 500 catch of POST /v1/document/upload. It fires when anything inside the try throws after the Collector checks: request.file missing (originalname undefined), Collector.processDocument throwing, Telemetry.sendTelemetry/EventLogs.logEvent throwing, or Document.api.uploadToWorkspace failing when addToWorkspaces points at a bad workspace. Note the handler already returns a structured 500 for an offline collector or a processDocument failure, so this bare 500 specifically means an UNCAUGHT exception — most often a missing request.file.

Source

Thrown at server/endpoints/api/document/index.js:170

        }

        Collector.log(
          `Document ${originalname} uploaded processed and successfully. It is now available in documents.`
        );
        await Telemetry.sendTelemetry("document_uploaded");
        await EventLogs.logEvent("api_document_uploaded", {
          documentName: originalname,
        });

        if (!!addToWorkspaces)
          await Document.api.uploadToWorkspace(
            addToWorkspaces,
            documents?.[0].location
          );
        response.status(200).json({ success: true, error: null, documents });
      } catch (e) {
        console.error(e.message, e);
        response.sendStatus(500).end();
      }
    }
  );

  app.post(
    "/v1/document/upload/:folderName",
    [validApiKey, handleAPIFileUpload, validateWorkspaceSlugQuery],
    async (request, response) => {
      /*
      #swagger.tags = ['Documents']
      #swagger.description = 'Upload a new file to a specific folder in AnythingLLM to be parsed and prepared for embedding. If the folder does not exist, it will be created.'
      #swagger.parameters['folderName'] = {
        in: 'path',
        description: 'Target folder path (defaults to \"custom-documents\" if not provided)',
        required: true,
        type: 'string',
        example: 'my-folder'
      }

View on GitHub (pinned to 526360e320)

Solutions

  1. Send the request as multipart/form-data with a file under the field name the middleware expects — a missing request.file is the most common cause.
  2. Confirm the Collector sidecar is reachable: GET /v1/system/health or the collector online check; an offline collector yields a structured 500, but a crashing one yields this bare 500.
  3. Omit addToWorkspaces or verify the target workspace exists before auto-distributing the document.
  4. Read the server log (console.error(e.message, e)) — this catch prints both the message and the full error.

Example fix

// before — JSON body, no file -> request.file undefined -> 500
await fetch('/v1/document/upload', {
  method: 'POST',
  headers: { Authorization: 'Bearer ' + apiKey, 'Content-Type': 'application/json' },
  body: JSON.stringify({})
});

// after — multipart form with a real file
const form = new FormData();
form.append('file', fs.createReadStream('./doc.txt'));
await fetch('/v1/document/upload', {
  method: 'POST',
  headers: { Authorization: 'Bearer ' + apiKey },
  body: form
});
Defensive patterns

Strategy: validation

Validate before calling

function isMultipartFileRequest(init) {
  const ct = (init.headers?.['Content-Type'] || init.headers?.['content-type'] || '');
  return ct.includes('multipart/form-data') && init.body instanceof FormData && Array.from(init.body.keys()).length > 0;
}

Type guard

function hasFileField(form) { return form instanceof FormData && Array.from(form.keys()).includes('file'); }

Try / catch

try {
  const r = await fetch('/v1/document/upload', { method: 'POST', headers, body: form });
  if (r.status === 500) {
    // structured 500 = collector offline / processDocument failure (has JSON body)
    // bare 500 (empty body) = uncaught throw, most often missing request.file
    const text = await r.text();
    throw new Error(text ? ('collector error: ' + text) : 'uncaught 500 — likely missing multipart file; see server logs');
  }
  return await r.json();
} catch (e) { throw e; }

Prevention

When it happens

Trigger: POST /v1/document/upload without a multipart file (request.file undefined -> `const { originalname } = request.file` throws); Collector.processDocument rejecting unexpectedly; addToWorkspaces set to a non-existent workspace so uploadToWorkspace throws; Telemetry/EventLogs throwing on an unrelated failure.

Common situations: Calling the endpoint with JSON body instead of multipart/form-data; missing the file field name the multer middleware expects; Collector (document-processing sidecar) crashing mid-parse; addToWorkspaces pointing at a deleted workspace; network blip to the Collector.

Understand the failure class

Related errors


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