docling-project/docling · error · RuntimeError

LibreOffice did not produce the expected output: {converted_

Error message

LibreOffice did not produce the expected output: {converted_path}

What it means

convert_with_soffice ran the LibreOffice subprocess successfully (exit code 0, within timeout) but the expected output file tmp_dir/<input-stem>.<target_suffix> does not exist afterwards, so it raises this RuntimeError naming the missing path. This means LibreOffice silently declined to produce that artifact — most often because the input file itself failed to import, or the output landed under a different name/suffix than expected.

Source

Thrown at docling/backend/docx/drawingml/utils.py:146

                [
                    libreoffice_cmd,
                    profile_arg,
                    "--headless",
                    "--convert-to",
                    target_suffix,
                    "--outdir",
                    str(tmp_dir),
                    str(input_path),
                ],
                stdout=subprocess.DEVNULL,
                stderr=subprocess.DEVNULL,
                check=True,
                timeout=timeout_s,
            )

        converted_path = tmp_dir / (input_path.stem + "." + target_suffix)
        if not converted_path.exists():
            raise RuntimeError(
                f"LibreOffice did not produce the expected output: {converted_path}"
            )

        return BytesIO(converted_path.read_bytes())
    finally:
        shutil.rmtree(tmp_dir, ignore_errors=True)


def get_docx_to_pdf_converter() -> Optional[Callable]:
    """
    Detects the best available DOCX to PDF tool and returns a conversion function.
    The returned function accepts (input_path, output_path).
    Returns None if no tool is available.
    """

    # Try LibreOffice
    libreoffice_cmd = get_libreoffice_cmd()

View on GitHub (pinned to 61d76f1ff3)

Solutions

  1. Open the file manually in LibreOffice (soffice --headless --convert-to pdf file.docx) and see whether it produces output; if not, the file is the problem — repair or re-export it.
  2. Remove password protection from the OOXML file before conversion.
  3. Free space / fix permissions in TMPDIR and pass a writable temp location.
  4. Check for an output written with a different suffix/case in the temp dir to identify naming mismatches, and report upstream if LibreOffice's suffix differs.

Example fix

# before
conv.convert(Path('drawing.docx'))  # soffice exits 0, no pdf produced

# after (diagnose outside docling first)
$ soffice --headless --convert-to pdf drawing.docx; ls drawing.pdf
# if missing -> repair/re-export or decrypt the docx, then rerun docling
Defensive patterns

Strategy: try-catch

Validate before calling

# Pre-flight the exact conversion outside docling:
import subprocess, tempfile, pathlib

def soffice_can_convert(path: pathlib.Path, target: str = "pdf") -> bool:
    with tempfile.TemporaryDirectory() as td:
        r = subprocess.run(["soffice", "--headless", "--convert-to", target,
                            "--outdir", td, str(path)],
                           capture_output=True, timeout=120)
        return r.returncode == 0 and bool(list(pathlib.Path(td).glob(f"*.{target}")))

Try / catch

try:
    result = conv.convert(docx_path)
except RuntimeError as e:
    if "did not produce the expected output" in str(e):
        if not soffice_can_convert(docx_path):
            quarantine(docx_path)  # file is unopenable by LibreOffice (corrupt/encrypted)
        else:
            report_upstream(docx_path, e)  # naming/temp-dir mismatch
    else:
        raise

Prevention

When it happens

Trigger: A source file (docx/pptx/xlsx) that LibreOffice cannot import (corrupt, password-protected OOXML, or not actually that format) — soffice exits 0 without writing output; case-sensitivity mismatches where LibreOffice writes a different-suffixed file; insufficient disk space or permissions in the temp dir; read-only or locked source under some viewers.

Common situations: Password-protected DOCX passed through the drawingml rasterization path; OOXML files produced by non-Office tools that LibreOffice rejects silently; concurrent conversions colliding in temp space; running headless where a modal import filter defaults differently.

Related errors


AI-assisted analysis of docling-project/docling@61d76f1ff3 (2026-08-14). Data as JSON: /api/errors/7bc9bf1aa79542c6. Report an issue: GitHub.