{"record":{"id":"1535761379d77c69","repo":"Mintplex-Labs/anything-llm","slug":"document-processing-is-unavailable-the-collector","errorCode":null,"errorMessage":"Document processing is unavailable. The collector service is offline.","messagePattern":"Document processing is unavailable\\. The collector service is offline\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/utils/telegramBot/utils/media.js","lineNumber":88,"sourceCode":" * @param {Buffer} documentBuffer\n * @param {string} originalFilename - The original filename with extension\n * @returns {Promise<{text: string, filename: string}>}\n */\nasync function documentToText(documentBuffer, originalFilename) {\n  const fs = require(\"fs\");\n  const path = require(\"path\");\n  const { CollectorApi } = require(\"../../collectorApi\");\n  const { hotdirPath } = require(\"../../files\");\n\n  if (!fs.existsSync(hotdirPath)) fs.mkdirSync(hotdirPath, { recursive: true });\n\n  const sanitizedName = originalFilename.replace(/[^a-zA-Z0-9._-]/g, \"_\");\n  const filename = `telegram-doc-${Date.now()}-${sanitizedName}`;\n  fs.writeFileSync(path.join(hotdirPath, filename), documentBuffer);\n\n  const collector = new CollectorApi();\n  if (!(await collector.online())) {\n    throw new Error(\n      \"Document processing is unavailable. The collector service is offline.\"\n    );\n  }\n\n  const result = await collector.parseDocument(filename);\n  if (!result?.success || !result.documents?.length) {\n    throw new Error(\n      result?.reason || `Failed to parse document: ${originalFilename}`\n    );\n  }\n\n  const text = result.documents.map((doc) => doc.pageContent).join(\"\\n\\n\");\n  return { text, filename: originalFilename };\n}\n\n/**\n * Download the largest photo from a Telegram photo array and return\n * it as an attachment object compatible with the LLM chat pipeline.","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/3aec848f2885144aa8f1e53b9731a04310d5d558/server/utils/telegramBot/utils/media.js#L70-L106","documentation":"Thrown in server/utils/telegramBot/utils/media.js when a Telegram user sends a document but the collector service (the separate Node process that parses documents) does not answer its online check (collector.online()). The document buffer has already been written to the hotdir; only parsing is refused. It is a dependency-availability error, not a document-format error.","triggerScenarios":"Telegram bot receives a file and calls processDocument -> collector.online() returns false because the collector process crashed, is still booting, or its HTTP port is unreachable from the server process.","commonSituations":"Collector crashed earlier (check storage/collector/logs or console output); docker deployment where the collector container is unhealthy or the COLLECTOR_ENDPOINT env points to the wrong host/port; resource exhaustion (OOM) killing the collector; sending a document immediately after server start before the collector is listening.","solutions":["Check collector logs (storage/collector/logs/ or container logs) for the crash reason and fix/restart it: docker compose restart collector.","Verify connectivity from the server container to the collector: curl the COLLECTATOR/collector endpoint (default http://collector:8888 or http://127.0.0.1:8888/collect).","Align COLLECTATOR env naming - confirm COLLECTOR_ENDPOINT matches the deployed collector port.","If OOM-killed, raise memory limits for the collector container.","Retry sending the document once the collector answers a health check."],"exampleFix":"// before\nif (!(await collector.online())) {\n  throw new Error('Document processing is unavailable. The collector service is offline.');\n}\n\n// after (caller-side guard + retry once at boot)\nfor (let i = 0; i < 5 && !(await collector.online()); i++) {\n  await new Promise((r) => setTimeout(r, 2000));\n}","handlingStrategy":"retry","validationCode":"const { CollectorApi } = require('./server/utils/collectorApi');\nconst collector = new CollectorApi();\nif (!(await collector.online())) {\n  return reply('Collector is starting up - please resend the document in a moment.');\n}","typeGuard":null,"tryCatchPattern":"try {\n  const text = await processDocument(buf, name);\n} catch (e) {\n  if (/collector service is offline/i.test(e.message)) {\n    await sleep(3000); // collector may still be booting\n    return processDocument(buf, name); // single retry\n  }\n  throw e;\n}","preventionTips":["Add a collector health check to container orchestration (depends_on with healthcheck) so the bot only receives documents when the collector is up.","Monitor collector logs for crash loops; the Telegram bot is usually the first caller to notice.","Keep COLLECTOR_ENDPOINT stable across restarts and aligned with the deployment topology."],"tags":["telegram","collector","service-availability","documents","network"],"backgroundTag":"service-unavailable","analyzedSha":"3aec848f2885144aa8f1e53b9731a04310d5d558","analyzedAt":"2026-08-18T10:02:21.017Z","contentChangedAt":"2026-08-18T10:02:21.017Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}