Mintplex-Labs/anything-llm · warning
Collector API is not online, skipping document attachment pr
Error message
Collector API is not online, skipping document attachment processing
What it means
During chat handling, AnythingLLM splits attachments into image vs document (mime application/anythingllm-document). Document attachments must be parsed and embedded by the separate Python "collector" service, so the handler first calls CollectorApi.online(), which is a plain fetch against http://0.0.0.0:COLLECTOR_PORT that returns true only on res.ok. When that probe fails, this warning is printed and parsedDocuments comes back empty — the chat still completes, but the model never sees the attachment's content.
Source
Thrown at server/utils/chats/apiChatHandler.js:67
const documentAttachments = [];
const imageAttachments = [];
for (const attachment of attachments) {
if (
attachment &&
attachment.contentString &&
attachment.mime &&
attachment.mime.toLowerCase() === "application/anythingllm-document"
)
documentAttachments.push(attachment);
else imageAttachments.push(attachment);
}
if (documentAttachments.length === 0)
return { parsedDocuments: [], imageAttachments };
const Collector = new CollectorApi();
const processingOnline = await Collector.online();
if (!processingOnline) {
console.warn(
"Collector API is not online, skipping document attachment processing"
);
return { parsedDocuments: [], imageAttachments };
}
if (!fs.existsSync(hotdirPath)) fs.mkdirSync(hotdirPath, { recursive: true });
const parsedDocuments = [];
for (const attachment of documentAttachments) {
try {
let base64Data = attachment.contentString;
const dataUriMatch = base64Data.match(/^data:[^;]+;base64,(.+)$/);
if (dataUriMatch) base64Data = dataUriMatch[1];
const buffer = Buffer.from(base64Data, "base64");
const filename = sanitizeFileName(
normalizePath(attachment.name || `attachment-${uuidv4()}`)
);
const filePath = normalizePath(path.join(hotdirPath, filename));View on GitHub (pinned to 20f6d3546c)
Solutions
- Check that the collector process/container is actually running: docker ps (or ps aux | grep collector) and inspect its logs for a crash; restart it (e.g. docker compose up -d collector).
- Verify the port: curl -f http://127.0.0.1:$COLLECTOR_PORT/ from the server container and confirm COLLECTOR_PORT matches the collector's real listen port and the compose port mapping.
- If the collector crash-loops, read its logs (python deps, OCR/whisper models, memory) and fix the underlying error before retrying.
- Re-send the chat with the attachment once the probe returns ok — the skipped documents are not retried retroactively.
Example fix
// before: silently degrades — chat answers without the attached document
const { parsedDocuments } = await parseAttachments({ attachments: msg.attachments });
// after: fail fast with an actionable error when documents are attached
const collectorOnline = await new CollectorApi().online();
const hasDocs = msg.attachments?.some(a => a.mime?.toLowerCase() === "application/anythingllm-document");
if (hasDocs && !collectorOnline) {
throw new Error("Document processing is offline — start the collector and resend this chat.");
} Defensive patterns
Strategy: validation
Validate before calling
import { CollectorApi } from "../utils/collectorApi";
const collector = new CollectorApi();
const hasDocAttachments = (attachments = []) =>
attachments.some(a => a.mime?.toLowerCase() === "application/anythingllm-document");
if (hasDocAttachments(req.body.attachments) && !(await collector.online())) {
return res.status(503).json({
error: "Document processing is temporarily unavailable. Remove document attachments or retry shortly.",
});
} Prevention
- Add a Docker healthcheck (curl -f http://127.0.0.1:PORT/) to the collector service and make the server depend_on it.
- Keep COLLECTOR_PORT identical in server and collector environments, including compose port mappings.
- Treat 'assistant ignores attached files' as the user-facing symptom of this warning and surface it in UI toasts rather than dropping context silently.
When it happens
Trigger: Sending a chat request whose attachments include mime "application/anythingllm-document" while the collector is stopped, crashed, OOM-killed, still booting, or listening on a different port than COLLECTOR_PORT. Any non-2xx response or connection error (ECONNREFUSED) from the collector endpoint produces the same path.
Common situations: Docker deployments where only the server container runs (collector exited after an image pull failure or crash-loop), bare-metal Node runs without starting the Python collector, COLLECTOR_PORT mismatches between containers, or racing collector startup during the first requests after boot. Users see the assistant answer while ignoring the attached PDF/DOCX.
Related errors
- Document processing is unavailable. The collector service is
- Not Found
- Invalid COLLECTOR_PORT "${process.env.COLLECTOR_PORT}". Fall
- Audio conversion failed.
- URL could not be scraped and no content was found.
AI-assisted analysis of Mintplex-Labs/anything-llm@20f6d3546c (2026-08-18).
Data as JSON: /api/errors/fb1a85af7f7c93bb.
Report an issue: GitHub.