{"record":{"id":"f0f269f83e390c2f","repo":"zylon-ai/private-gpt","slug":"document-conversion-failed-with-status-conversio","errorCode":null,"errorMessage":"Document conversion failed with status: {conversion_result.status}. Errors: {conversion_result.errors}","messagePattern":"Document conversion failed with status: (.+?)\\. Errors: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"private_gpt/components/readers/docling/docling_api_reader.py","lineNumber":173,"sourceCode":"        **load_kwargs: Any,\n    ) -> AsyncIterator[BaseNode]:\n        \"\"\"Lazy load file data into LlamaIndex Documents.\"\"\"\n        logger.debug(\"Starting Docling API parsing of file: %s\", file_info.file_name)\n\n        file_name = file_info.file_name or file_info.file_data.name\n        file_data = file_info.file_data\n        file_bytes = await asyncio.to_thread(file_data.read_bytes)\n        pages = file_info.config.get(\"pages\", None)\n\n        try:\n            conversion_result = await self.client.convert_from_bytes(\n                file_name, file_bytes, to_formats=[\"md\"], pages=pages, **load_kwargs\n            )\n        except Exception as e:\n            raise ValueError(f\"Document conversion failed: {e}\") from e\n\n        if conversion_result.status not in [\"success\", \"partial_success\"]:\n            raise ValueError(\n                f\"Document conversion failed with status: {conversion_result.status}. \"\n                f\"Errors: {conversion_result.errors}\"\n            )\n\n        contents = self._get_content(conversion_result)\n        valid_contents = [content for content in contents if content]\n        if not valid_contents:\n            raise ValueError(\"No valid document content found after conversion\")\n        if self._is_extraction_unsuccessful(valid_contents):\n            raise ExtractionUnsuccessfulError(\n                f\"Document extraction unsuccessful for '{file_name}': unmapped-glyph \"\n                f\"ratio exceeded threshold ({self.config.failure_threshold}).\"\n            )\n\n        docs = [\n            self._page_to_doc(\n                content=content,\n                index=idx,","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/zylon-ai/private-gpt/blob/4a030776a31a901ad80b1bf4d7faa2c1a367efbb/private_gpt/components/readers/docling/docling_api_reader.py#L155-L191","documentation":"Raised by DoclingApiReader.lazy_load_data when the conversion result's status is neither 'success' nor 'partial_success'. Unlike the async-client failure path (error 181), this is the synchronous response from Docling already carrying a failure status — typically 'failure' — and the message appends the server's own errors list, which is the primary diagnostic.","triggerScenarios":"POST /convert/source (sync path) returning JSON with status: 'failure' and a populated errors array: unparseable document, invalid pdf_backend for the file type, OCR engine crash on the server, abort_on_error triggered by a page-level error.","commonSituations":"Corrupt/encrypted PDFs; documents in from_formats not enabled server-side; pdf_backend mismatch (e.g., file needs a different parser); partial failures when abort_on_error defaults to true; Docling server version changes altering error semantics.","solutions":["Read the Errors: [...] portion of the message — it is the server's own error list and names the failing component directly.","Retry the file against the server API directly with the same options to reproduce and iterate quickly.","For page-level errors, ingest a page subset (pages config) to isolate the bad pages, or relax options (disable OCR/table structure enrichment).","If the file itself is corrupt (common for downloaded/merged PDFs), repair or skip it; no server config will help.","Move the file to a dead-letter/quarantine path so one bad file does not stop the batch."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"def is_acceptable_status(status: str) -> bool:\n    return status in {\"success\", \"partial_success\"}","tryCatchPattern":"try:\n    nodes = [n async for n in reader.lazy_load_data(file_info)]\nexcept ValueError as e:\n    msg = str(e)\n    if \"failed with status\" in msg:\n        server_errors = msg.split(\"Errors:\", 1)[-1]\n        quarantine(file_info, reason=server_errors)  # terminal; log server's errors list\n        return []\n    raise","preventionTips":["Reproduce single-file failures by posting to the server API directly — the errors array names the failing component.","Use the pages config to bisect documents with one poison page.","Keep abort_on_error semantics in mind: one bad page can fail the whole document."],"tags":["docling","conversion-status","ingestion","server-side-failure"],"backgroundTag":null,"analyzedSha":"4a030776a31a901ad80b1bf4d7faa2c1a367efbb","analyzedAt":"2026-08-15T03:51:26.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}