Mintplex-Labs/anything-llm · error

${reason}

Error message

${reason}

What it means

The server forwards `reason` from Collector.processRawText when the internal Python collector fails to turn the posted text into a document on POST /browser-extension/embed-content. CollectorApi.processRawText never throws - it catches its own fetch errors and returns { success:false, reason }, so the reason string is either the fetch failure text (collector unreachable) or 'Response could not be completed' (collector returned a non-2xx, e.g. integrity-key/version mismatch). The document was never produced, so nothing reaches the workspace.

Source

Thrown at server/endpoints/browserExtension.js:104

        const { workspaceId, textContent, metadata } = reqBody(request);
        const user = await userFromSession(request, response);
        const workspace = multiUserMode(response)
          ? await Workspace.getWithUser(user, { id: parseInt(workspaceId) })
          : await Workspace.get({ id: parseInt(workspaceId) });

        if (!workspace) {
          response.status(404).json({ error: "Workspace not found" });
          return;
        }

        const Collector = new CollectorApi();
        const { success, reason, documents } = await Collector.processRawText(
          textContent,
          metadata
        );

        if (!success) {
          response.status(500).json({ success: false, error: reason });
          return;
        }

        const { failedToEmbed = [], errors = [] } = await Document.addDocuments(
          workspace,
          [documents[0].location],
          user?.id
        );

        if (failedToEmbed.length > 0) {
          response.status(500).json({ success: false, error: errors[0] });
          return;
        }

        await Telemetry.sendTelemetry("browser_extension_embed_content");
        response.status(200).json({ success: true });
      } catch (error) {
        console.error(error);

View on GitHub (pinned to 3aec848f28)

Solutions

  1. Read the reason field verbatim - it is the collector-side message and distinguishes unreachable vs failed-processing.
  2. Check collector logs (docker compose logs, or the collector output inside the all-in-one container) for a stack trace matching the request time.
  3. Restart the server/collector pair to clear version-drift or crashed-collector states and retry the embed.
  4. Trim oversized/binary-laden textContent before sending; empty selections will always fail.
Defensive patterns

Strategy: retry

Validate before calling

const text = (textContent ?? '').trim();
if (!text) throw new Error('Nothing to embed: page selection is empty');
if (metadata != null && typeof metadata !== 'object') throw new Error('metadata must be an object');

Type guard

const isCollectorFailure = (r: unknown): r is { success: false; reason: string } =>
  typeof r === 'object' && r !== null && (r as any).success === false && typeof (r as any).reason === 'string';

Try / catch

for (let attempt = 1; attempt <= 3; attempt++) {
  const res = await embedContent(apiKey, payload);
  if (res.status === 200) break;
  if (res.status === 500 && /reason/i.test(JSON.stringify(res.body))) {
    await sleep(1000 * attempt); // collector handshake failures are often transient
    continue;
  }
  throw new Error(`Embed failed: ${res.body?.error}`);
}

Prevention

When it happens

Trigger: Collector sidecar process/container not running (ECONNREFUSED text in reason); collector returned 4xx/5xx on /process-raw-text, which processRawText flattens to 'Response could not be completed'; textContent empty or unparseable so the collector rejects the job; collector OOM-killed mid-request.

Common situations: Custom deployments where the python collector service failed to boot; version drift between server and collector after a partial upgrade; very large page captures exhausting collector memory.

Related errors


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