{"record":{"id":"bebbc6110c25a40d","repo":"opendataloader-project/opendataloader-pdf","slug":"conversion-completed-but-no-ext-output-file-wa","errorCode":null,"errorMessage":"Conversion completed but no '{ext}' output file was generated.","messagePattern":"Conversion completed but no '(.+?)' output file was generated\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"python/opendataloader-pdf-mcp/src/opendataloader_pdf_mcp/server.py","lineNumber":166,"sourceCode":"            kwargs[\"hybrid_fallback\"] = True\n        if image_dir is not None:\n            kwargs[\"image_dir\"] = image_dir\n\n        opendataloader_pdf.convert(**kwargs)\n\n        # Find and read the output file\n        stem = input_file.stem\n        output_file = Path(tmp_dir) / f\"{stem}{ext}\"\n\n        if not output_file.is_file():\n            files = [f for f in Path(tmp_dir).iterdir() if f.is_file()]\n            if not files:\n                raise RuntimeError(\n                    \"Conversion completed but no output file was generated.\"\n                )\n            matching_ext = sorted(f for f in files if f.suffix == ext)\n            if not matching_ext:\n                raise RuntimeError(\n                    f\"Conversion completed but no '{ext}' output file was generated.\"\n                )\n            output_file = matching_ext[0]\n\n        return output_file.read_text(encoding=\"utf-8\")\n\n\ndef main():\n    \"\"\"Run the MCP server.\"\"\"\n    mcp.run()\n\n\nif __name__ == \"__main__\":\n    main()\n","sourceCodeStart":148,"sourceCodeEnd":181,"githubUrl":"https://github.com/opendataloader-project/opendataloader-pdf/blob/a7789b8e77dd05e2b8659eb3ea12fc458f80bfb8/python/opendataloader-pdf-mcp/src/opendataloader_pdf_mcp/server.py#L148-L181","documentation":"RuntimeError raised when convert() returned, the expected {stem}{ext} output is absent, but OTHER files DO exist in the temp dir (none with the matching extension). This points to a filename mismatch: the Java CLI wrote output using a different stem or extension than the Python wrapper predicted from input_file.stem + ext_map. The wrapper then cannot locate the result even though conversion succeeded.","triggerScenarios":"input_file.stem differs from the stem the Java CLI uses for the output filename — e.g. the CLI sanitizes/replaces characters, uses the PDF's internal /Title, or appends a suffix. Or the output extension differs from ext_map's mapping for the chosen format (e.g. tagged-pdf vs pdf, or a format that produces a directory not a single file).","commonSituations":"Source filename contains characters the CLI normalizes (spaces, unicode) so the output stem differs. The format produces a bundle/directory rather than a single file. A version change altered the CLI's output naming convention while the MCP wrapper's prediction stayed fixed.","solutions":["List the temp dir contents when debugging: the present files reveal the actual naming the CLI used (e.g. a sanitized stem or a different extension).","Avoid filenames with characters the CLI may rewrite; use ASCII filenames without spaces for predictable output stems.","Confirm the format maps to a single file, not a directory (e.g. image extraction can produce multiple files).","After changing CLI output behaviour, ensure the MCP wrapper's stem/ext prediction stays in sync (run npm run sync)."],"exampleFix":"# before: stem mismatch — file is 'My Report.pdf' -> output stem 'My_Report'\nconvert(input_path=\"My Report.pdf\", format=\"markdown\")  # looks for 'My Report.md'\n# after: ASCII filename without spaces\nconvert(input_path=\"my_report.pdf\", format=\"markdown\")  # finds 'my_report.md'","handlingStrategy":"validation","validationCode":"# Pre-check: use ASCII filenames without spaces so the CLI's output stem matches input_file.stem.\nimport re\ndef safe_stem(path: str) -> bool:\n    stem = Path(path).stem\n    return bool(re.fullmatch(r\"[A-Za-z0-9_.-]+\", stem))\n","typeGuard":"def is_extension_mismatch_error(exc: RuntimeError) -> bool:\n    return isinstance(exc, RuntimeError) and \"output file was generated.\" in str(exc) and \"'\" in str(exc)","tryCatchPattern":"try:\n    text = convert(input_path=path, format=\"markdown\")\nexcept RuntimeError as e:\n    if \"output file was generated.\" in str(e) and \"'\" in str(e):\n        # other files exist but none match ext — list tmp_dir to find the real name\n        log.warning(\"Output stem/ext mismatch; rename input to ASCII without spaces and retry\")\n    raise","preventionTips":["Use ASCII filenames without spaces/unicode for predictable output stems.","Confirm the format produces a single file, not a directory or multiple files (image extraction can split output).","Run npm run sync after changing CLI output naming so the MCP wrapper stays aligned."],"tags":["mcp","output-naming","stem-mismatch","subprocess","python"],"backgroundTag":null,"analyzedSha":"a7789b8e77dd05e2b8659eb3ea12fc458f80bfb8","analyzedAt":"2026-08-14T05:22:03.953Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}