{"record":{"id":"1dba2983ac950b05","repo":"run-llama/liteparse","slug":"data","errorCode":null,"errorMessage":"{data}","messagePattern":"\\{data\\}","errorType":"exception","errorClass":"ParseError","httpStatus":null,"severity":"error","filePath":"packages/python/liteparse/_pool.py","lineNumber":270,"sourceCode":"            replace = True\n            raise ParseError(\n                f\"liteparse worker process died while parsing {source}: {e}\"\n            ) from None\n        except _WorkerInitFailed as e:\n            replace = True\n            raise ParseError(f\"liteparse worker failed to initialize: {e}\") from None\n        finally:\n            if replace:\n                self._retire_worker(worker)\n                if not self._closed:\n                    self._spawn_worker()\n            elif self._closed:\n                worker.stop()\n            else:\n                self._idle.put(worker)\n        if status == \"ok\":\n            return data\n        raise ParseError(data)\n\n    def warm_up(self) -> None:\n        \"\"\"Block until every worker has finished initializing.\n\n        Optional — the first parse per worker waits for init anyway. Useful\n        before latency-sensitive traffic or benchmarks.\n        \"\"\"\n        workers = list(self._workers)\n        for worker in workers:\n            worker._ensure_ready()\n\n    def close(self) -> None:\n        \"\"\"Shut down all workers. Idempotent.\"\"\"\n        if self._closed:\n            return\n        self._closed = True\n        # Stop the workers we can grab; busy workers are stopped by parse()'s\n        # finally-block when they come back (see the _closed check there).","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/run-llama/liteparse/blob/22d2dd8cd7f7b9320102b57ddaf0e663ff7d15a8/packages/python/liteparse/_pool.py#L252-L288","documentation":"Raised when the worker completed the request but reported a non-ok status: the message is the verbatim '{ExceptionType}: {detail}' string produced inside the worker when native parsing raised. This is the normal channel for in-process parse failures (corrupt PDFs, unsupported files, native errors) when using the pool — the actual exception type is flattened into a string inside ParseError.","triggerScenarios":"Any parse() / parse_bytes() call on a pooled LiteParse where native.parse() or native.parse_bytes() raises inside the worker: malformed/encrypted PDF, file path unreadable by the worker, unsupported format, conversion tool (LibreOffice) missing, etc.","commonSituations":"Passing an encrypted or corrupt PDF; pointing at a path that exists for the parent but not in the worker's context; DOCX/XLSX conversion failing because LibreOffice is not installed; anything that would throw the underlying native exception without a pool.","solutions":["Read the leading type name in the message (e.g. 'FileNotFoundError: ...') — it is the native exception flattened to a string","If it is a missing converter, install the external tool (e.g. LibreOffice) on the machine running the workers","If it is a corrupt/encrypted PDF, validate or decrypt the document before parsing","Confirm the file path is absolute and readable from the worker process (the worker parses the path independently)","If the message hides too much detail, run once without pool_size to get the full native traceback"],"exampleFix":"# before\nparser = LiteParse(pool_size=2)\nresult = parser.parse(\"doc.docx\")  # ParseError: IOException: soffice not found\n\n# after\n# install the converter first, e.g.: apt-get install -y libreoffice\nimport shutil\nassert shutil.which(\"soffice\"), \"LibreOffice required for office formats\"\nresult = LiteParse(pool_size=2).parse(\"doc.docx\")","handlingStrategy":"try-catch","validationCode":"from pathlib import Path\ndef assert_parsable_input(file_data) -> None:\n    if isinstance(file_data, str):\n        p = Path(file_data)\n        if not p.is_file():\n            raise FileNotFoundError(p)\n        if p.suffix.lower() in {\".docx\", \".xlsx\", \".pptx\"} and not shutil.which(\"soffice\"):\n            raise RuntimeError(\"LibreOffice (soffice) required for office formats\")","typeGuard":null,"tryCatchPattern":"from liteparse.types import ParseError\ntry:\n    result = parser.parse(path)\nexcept ParseError as e:\n    # message is 'ExceptionType: detail' from the worker\n    kind, _, detail = str(e).partition(\": \")\n    log.error(\"parse failed (%s): %s\", kind, detail)\n    raise","preventionTips":["Parse the message prefix to recover the original exception type","Install external converters (LibreOffice) wherever workers run","Pre-validate PDFs (not encrypted, correct magic bytes) before parsing","Debug inscrutable messages by running the same input without pool_size for a full traceback"],"tags":["parse","worker-pool","propagated-exception"],"backgroundTag":"api-error-response","analyzedSha":"22d2dd8cd7f7b9320102b57ddaf0e663ff7d15a8","analyzedAt":"2026-09-08T06:09:49.009Z","contentChangedAt":"2026-09-08T06:09:49.009Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}