opendataloader-project/opendataloader-pdf · error · FileNotFoundError
Input file not found: {input_path}
Error message
Input file not found: {input_path} What it means
FileNotFoundError raised by the MCP convert tool after Path(input_path).expanduser().resolve() when the resolved path is not a regular file. Because expanduser+resolve run first, the message echoes the ORIGINAL input_path (which may differ from the resolved absolute path), and symlinks/relative paths are resolved against the MCP server's cwd.
Source
Thrown at python/opendataloader-pdf-mcp/src/opendataloader_pdf_mcp/server.py:77
text_page_separator: Separator between pages in text output.
html_page_separator: Separator between pages in HTML output.
image_output: Image output mode. Values: off, embedded, external.
image_format: Image format. Values: png, jpeg.
include_header_footer: Include page headers and footers in output.
detect_strikethrough: Detect strikethrough text (experimental).
hybrid: Hybrid backend. Values: off, docling-fast.
hybrid_mode: Hybrid triage mode. Values: auto, full.
hybrid_url: Hybrid backend server URL.
hybrid_timeout: Hybrid backend timeout in milliseconds.
hybrid_fallback: Enable Java fallback on hybrid backend error.
image_dir: Directory path to save extracted images.
Returns:
The converted content as text.
"""
input_file = Path(input_path).expanduser().resolve()
if not input_file.is_file():
raise FileNotFoundError(f"Input file not found: {input_path}")
# Determine output file extension from format
ext_map = {
"json": ".json",
"text": ".txt",
"html": ".html",
"markdown": ".md",
"markdown-with-html": ".md",
"markdown-with-images": ".md",
}
if format not in ext_map:
raise ValueError(
f"Unsupported format: {format!r}. "
f"Supported formats: {', '.join(ext_map)}"
)
ext = ext_map[format]
with tempfile.TemporaryDirectory() as tmp_dir:View on GitHub (pinned to a7789b8e77)
Solutions
- Send an absolute path to the MCP tool to avoid cwd-dependent resolution.
- Verify the file exists from the server's perspective: ensure the path is reachable by the process running the MCP server (mounts, permissions).
- Check for typos and the correct extension (.pdf).
- If using a symlink, confirm the target exists (readlink -f).
Example fix
# before: relative path resolved from server cwd, not found convert(input_path="~/reports/q3.pdf") # '~' expanded but file absent -> error # after: absolute, verified path convert(input_path="/home/user/reports/q3.pdf")
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def ensure_input(input_path: str) -> Path:
p = Path(input_path).expanduser().resolve()
if not p.is_file():
raise FileNotFoundError(f"Input file not found: {input_path}")
return p
Type guard
def is_valid_input(input_path: str) -> bool:
try:
return Path(input_path).expanduser().resolve().is_file()
except OSError:
return False Try / catch
try:
result = convert(input_path=path, format="markdown")
except FileNotFoundError as e:
# message echoes the original input_path
return {"error": str(e), "hint": "send an absolute, verified path"} Prevention
- Send absolute paths to the MCP tool to avoid cwd-dependent resolution.
- Verify Path(...).is_file() on the client side before invoking the tool.
- Remember the message echoes the ORIGINAL input_path, not the resolved absolute path.
When it happens
Trigger: Calling the MCP server's convert tool with a path that does not exist on disk, a broken symlink, a path relative to a different cwd than the server runs in, or a path with a typo.
Common situations: Client sends a relative path assuming the user's home, but the server resolves from its own working directory. A path with a typo or wrong extension. An NFS/mount path not available inside the server's container. A deleted file referenced by a stale bookmark.
Related errors
- Unsupported format: {format!r}. Supported formats: {', '.joi
- Conversion completed but no output file was generated.
- Conversion completed but no '{ext}' output file was generate
- no SKILL.md found under {skill_dir} (nothing to lint)
- Unsupported table method '%s'. Supported values: %s
AI-assisted analysis of opendataloader-project/opendataloader-pdf@a7789b8e77 (2026-08-14).
Data as JSON: /api/errors/af8dd101a446a236.
Report an issue: GitHub.