{"record":{"id":"0c6bc4234d60d534","repo":"Mintplex-Labs/anything-llm","slug":"reason-0c6bc4","errorCode":null,"errorMessage":"${reason}","messagePattern":"\\$\\{reason\\}","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"server/endpoints/browserExtension.js","lineNumber":104,"sourceCode":"        const { workspaceId, textContent, metadata } = reqBody(request);\n        const user = await userFromSession(request, response);\n        const workspace = multiUserMode(response)\n          ? await Workspace.getWithUser(user, { id: parseInt(workspaceId) })\n          : await Workspace.get({ id: parseInt(workspaceId) });\n\n        if (!workspace) {\n          response.status(404).json({ error: \"Workspace not found\" });\n          return;\n        }\n\n        const Collector = new CollectorApi();\n        const { success, reason, documents } = await Collector.processRawText(\n          textContent,\n          metadata\n        );\n\n        if (!success) {\n          response.status(500).json({ success: false, error: reason });\n          return;\n        }\n\n        const { failedToEmbed = [], errors = [] } = await Document.addDocuments(\n          workspace,\n          [documents[0].location],\n          user?.id\n        );\n\n        if (failedToEmbed.length > 0) {\n          response.status(500).json({ success: false, error: errors[0] });\n          return;\n        }\n\n        await Telemetry.sendTelemetry(\"browser_extension_embed_content\");\n        response.status(200).json({ success: true });\n      } catch (error) {\n        console.error(error);","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/3aec848f2885144aa8f1e53b9731a04310d5d558/server/endpoints/browserExtension.js#L86-L122","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Read the reason field verbatim - it is the collector-side message and distinguishes unreachable vs failed-processing.","Check collector logs (docker compose logs, or the collector output inside the all-in-one container) for a stack trace matching the request time.","Restart the server/collector pair to clear version-drift or crashed-collector states and retry the embed.","Trim oversized/binary-laden textContent before sending; empty selections will always fail."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"const text = (textContent ?? '').trim();\nif (!text) throw new Error('Nothing to embed: page selection is empty');\nif (metadata != null && typeof metadata !== 'object') throw new Error('metadata must be an object');","typeGuard":"const isCollectorFailure = (r: unknown): r is { success: false; reason: string } =>\n  typeof r === 'object' && r !== null && (r as any).success === false && typeof (r as any).reason === 'string';","tryCatchPattern":"for (let attempt = 1; attempt <= 3; attempt++) {\n  const res = await embedContent(apiKey, payload);\n  if (res.status === 200) break;\n  if (res.status === 500 && /reason/i.test(JSON.stringify(res.body))) {\n    await sleep(1000 * attempt); // collector handshake failures are often transient\n    continue;\n  }\n  throw new Error(`Embed failed: ${res.body?.error}`);\n}","preventionTips":["Keep collector and server on the same release so the X-Integrity handshake matches.","Monitor the collector sidecar and restart it with the server, never independently.","Strip huge/binary content from captured text before posting."],"tags":["browser-extension","collector","document-processing","http-500"],"backgroundTag":"document-processing-failed","analyzedSha":"3aec848f2885144aa8f1e53b9731a04310d5d558","analyzedAt":"2026-08-18T10:02:21.017Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}