opendataloader-project/opendataloader-pdf · error · RuntimeError
Conversion completed but no output file was generated.
Error message
Conversion completed but no output file was generated.
What it means
RuntimeError raised when opendataloader_pdf.convert() returned without throwing, but the temp directory contains NO files at all — neither the expected {stem}{ext} nor any other file. This indicates the underlying conversion produced zero output: the Java process likely exited abnormally (crash, OOM kill) or wrote nothing and returned a success-like exit that the wrapper did not flag.
Source
Thrown at python/opendataloader-pdf-mcp/src/opendataloader_pdf_mcp/server.py:161
if hybrid_url is not None:
kwargs["hybrid_url"] = hybrid_url
if hybrid_timeout is not None:
kwargs["hybrid_timeout"] = hybrid_timeout
if hybrid_fallback:
kwargs["hybrid_fallback"] = True
if image_dir is not None:
kwargs["image_dir"] = image_dir
opendataloader_pdf.convert(**kwargs)
# Find and read the output file
stem = input_file.stem
output_file = Path(tmp_dir) / f"{stem}{ext}"
if not output_file.is_file():
files = [f for f in Path(tmp_dir).iterdir() if f.is_file()]
if not files:
raise RuntimeError(
"Conversion completed but no output file was generated."
)
matching_ext = sorted(f for f in files if f.suffix == ext)
if not matching_ext:
raise RuntimeError(
f"Conversion completed but no '{ext}' output file was generated."
)
output_file = matching_ext[0]
return output_file.read_text(encoding="utf-8")
def main():
"""Run the MCP server."""
mcp.run()
if __name__ == "__main__":View on GitHub (pinned to a7789b8e77)
Solutions
- Run the same conversion via the CLI directly (odl-pdf <file>) outside the MCP server to see the real subprocess stderr/exit code.
- If the JVM is OOM-killed, raise the container/process memory limit or pass -Xmx to the JVM.
- Verify the JAR is present and valid (the Python package's bundled jar); reinstall the package if the build hook (hatch_build.py) failed to copy it.
- Check dmesg/journal for an OOM kill of the java process during conversion.
Example fix
# before: silent empty output, cause hidden convert(...); # RuntimeError, no clue # after: run the CLI directly to surface the real error $ odl-pdf doc.pdf -o /tmp/out # -> reveals 'java.lang.OutOfMemoryError' or 'jar not found'
Defensive patterns
Strategy: try-catch
Validate before calling
# No pre-check; instead, surface the real subprocess error by running the CLI directly first: # odl-pdf <file> -o /tmp/out # and check exit code + stderr before relying on the MCP wrapper.
Type guard
def is_empty_output_error(exc: RuntimeError) -> bool:
return isinstance(exc, RuntimeError) and "no output file was generated" in str(exc) and "'" not in str(exc) Try / catch
try:
text = convert(input_path=path, format="markdown")
except RuntimeError as e:
msg = str(e)
if "no output file was generated" in msg and "'" not in msg:
# zero files — likely JVM crash/OOM; run the CLI to see real stderr
import subprocess
subprocess.run(["odl-pdf", path, "-o", "/tmp/out"], check=True)
raise Prevention
- Raise the container/process memory limit if the JVM is OOM-killed on large PDFs.
- Verify the bundled JAR exists and is valid before serving requests.
- Smoke-test conversion with the CLI directly to capture subprocess stderr the MCP wrapper hides.
When it happens
Trigger: MCP convert tool runs opendataloader_pdf.convert(**kwargs) into a TemporaryDirectory; on return, Path(tmp_dir).iterdir() yields no files. Happens when the JVM is killed (OOM, SIGKILL in a cgroup), the CLI binary is missing/broken, or convert swallowed a subprocess failure.
Common situations: Container memory limit too low so the JVM is OOM-killed mid-conversion on a large PDF. The packaged JAR is missing or corrupt so the CLI exits immediately without writing output. A misconfigured JAVA_HOME/CLI path invoking the wrong binary.
Related errors
- Conversion completed but no '{ext}' output file was generate
- Input file not found: {input_path}
- Unsupported format: {format!r}. Supported formats: {', '.joi
- Missing dependencies: {', '.join(missing)}. Install with: pi
- OCR engine '{ocr_engine}' is not supported in hybrid local m
AI-assisted analysis of opendataloader-project/opendataloader-pdf@a7789b8e77 (2026-08-14).
Data as JSON: /api/errors/391edb55aab05335.
Report an issue: GitHub.