{"record":{"id":"cd5534078b89ae2c","repo":"iflytek/astron-agent","slug":"chunkqueryfailed","errorCode":"ChunkQueryFailed","errorMessage":"RAGFlow produced zero chunks for document {doc_id}","messagePattern":"RAGFlow produced zero chunks for document (.+?)","errorType":"error_code","errorClass":"CustomException","httpStatus":null,"severity":"error","filePath":"core/knowledge/service/impl/ragflow_strategy.py","lineNumber":337,"sourceCode":"            doc_id,\n            final_status,\n        )\n\n    def _validate_document_chunks(\n        self,\n        doc_id: str,\n        chunks_data: List[Dict[str, Any]],\n    ) -> None:\n        \"\"\"Reject empty RAGFlow output.\n\n        A large single chunk is valid when the source contains no configured\n        delimiter: RAGFlow v0.20.5's naive merger does not forcibly split one\n        oversized segment. Console therefore stores such chunks in LONGTEXT\n        instead of treating their size as proof that configuration was ignored.\n        \"\"\"\n        if not chunks_data:\n            logger.error(\"RAGFlow produced zero chunks: doc=%s\", doc_id)\n            raise CustomException(\n                CodeEnum.ChunkQueryFailed,\n                f\"RAGFlow produced zero chunks for document {doc_id}\",\n            )\n\n    async def split(\n        self,\n        fileUrl: Optional[str] = None,\n        lengthRange: Optional[List[int]] = None,\n        overlap: int = 16,\n        resourceType: int = 0,\n        separator: Optional[List[str]] = None,\n        titleSplit: bool = False,\n        cutOff: Optional[List[str]] = None,\n        document_id: Optional[str] = None,\n        **kwargs: Any,\n    ) -> List[Dict[str, Any]]:\n        \"\"\"\n        Split file into chunks using RAGFlow.","sourceCodeStart":319,"sourceCodeEnd":355,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/knowledge/service/impl/ragflow_strategy.py#L319-L355","documentation":"Raised by _validate_document_chunks (core/knowledge/service/impl/ragflow_strategy.py:337) when RAGFlow finished parsing a document but returned zero chunks. Split/upsert treat an empty chunk set as a failed ingestion (CustomException with ChunkQueryFailed) and roll back the newly uploaded document, because empty output usually means parsing produced nothing usable.","triggerScenarios":"Calling split() (fresh upload path or _upsert_document) where get_document_chunks returns [] after wait_for_parsing reports completion — e.g. the document contains no extractable text (image-only PDF, empty file), the parser failed silently, or wait_for_parsing timed out and reported an interim status as final.","commonSituations":"Uploading scanned/image PDFs without OCR enabled in the RAGFlow parser config; uploading a file whose format RAGFlow's parser cannot extract (encrypted PDF, exotic format); RAGFlow parse 'completed' with RUN status FAIL or a zero-chunk DONE due to version quirks; chunk_token_num/separator config excludes all content.","solutions":["Check the document's run status in RAGFlow — if FAIL, read the parse error and fix the file or parser config before retrying.","Verify the source file actually contains extractable text (open it or run pdftotext); use an OCR-capable parser for scanned documents.","Try parsing with default parser_config to rule out a separator/chunk_token_num setting that filters out all content.","Increase wait_for_parsing timeout (currently 300s) for very large documents that may still be parsing when chunks are fetched.","If the file legitimately has no text, reject it upstream instead of uploading to RAGFlow."],"exampleFix":"// before: uploading image-only PDF with naive parser\nchunks = await strategy.split(fileUrl=scan_pdf_url)\n\n// after: reject empty/unextractable inputs and verify parse status\nif not extractable_text(file_content):\n    raise ValueError(\"File contains no extractable text; OCR required\")\nchunks = await strategy.split(fileUrl=scan_pdf_url)\n// on ChunkQueryFailed, inspect doc run status:\ndoc = await ragflow_client.get_document_info(dataset_id, doc_id)\nlogger.info(\"run status: %s\", doc.get(\"run\"))","handlingStrategy":"validation","validationCode":"# before uploading, ensure the source has extractable text\ntext = extract_text_preview(file_content)  # e.g. pdftotext / docx read\nif not text.strip():\n    raise ValueError(\"file contains no extractable text (OCR needed?)\")","typeGuard":"def chunks_nonempty(chunks_data) -> bool:\n    return isinstance(chunks_data, list) and len(chunks_data) > 0","tryCatchPattern":"try:\n    chunks = await strategy.split(fileUrl=url)\nexcept CustomException as e:\n    if e.code == CodeEnum.ChunkQueryFailed:\n        doc = await ragflow_client.get_document_info(dataset_id, e.doc_id)\n        logger.error(\"parse ended run=%s with zero chunks\", doc and doc.get(\"run\"))\n    raise","preventionTips":["Reject scanned/image-only files without an OCR-capable parser config.","Verify parse run status (FAIL vs DONE) when zero chunks are returned.","Increase the 300s wait_for_parsing timeout for large documents.","Test suspicious files with default parser_config to isolate config-induced empty output."],"tags":["ragflow","chunking","empty-result","parsing"],"backgroundTag":"empty-result-set","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}