opendatalab/MinerU · error · ValueError

Input path must be a file or directory: {path}

Error message

Input path must be a file or directory: {path}

What it means

Raised by collect_input_files() when the path exists and is neither a regular file nor a directory — i.e. it is a special filesystem node such as a FIFO, socket, device, or a broken symlink that resolve() still passes exists() for in some configurations. The function only accepts regular files and directories.

Source

Thrown at demo/demo.py:28

from mineru.cli.common import image_suffixes, office_suffixes, pdf_suffixes
from mineru.utils.guess_suffix_or_lang import guess_suffix_by_path

SUPPORTED_INPUT_SUFFIXES = set(pdf_suffixes + image_suffixes + office_suffixes)


def collect_input_files(input_path: str | Path) -> list[Path]:
    path = Path(input_path).expanduser().resolve()
    if not path.exists():
        raise FileNotFoundError(f"Input path does not exist: {path}")

    if path.is_file():
        file_suffix = guess_suffix_by_path(path)
        if file_suffix not in SUPPORTED_INPUT_SUFFIXES:
            raise ValueError(f"Unsupported input file type: {path.name}")
        return [path]

    if not path.is_dir():
        raise ValueError(f"Input path must be a file or directory: {path}")

    input_files = sorted(
        (
            candidate.resolve()
            for candidate in path.iterdir()
            if candidate.is_file()
            and guess_suffix_by_path(candidate) in SUPPORTED_INPUT_SUFFIXES
        ),
        key=lambda item: item.name,
    )
    if not input_files:
        raise ValueError(f"No supported files found in directory: {path}")
    return input_files


def build_form_data(
    language: str,
    backend: str,

View on GitHub (pinned to 4fe4bde114)

Solutions

  1. Write the streamed data to a real temporary file first, then pass that file's path.
  2. If you intended a directory or file, check for a typo or a symlink resolving to a special node.

Example fix

# before
files = collect_input_files("/dev/stdin")

# after
import tempfile, sys
with tempfile.NamedTemporaryFile(suffix=".pdf", delete=False) as f:
    f.write(sys.stdin.buffer.read())
files = collect_input_files(f.name)
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path

def is_regular_file_or_dir(value: str) -> bool:
    p = Path(value).expanduser().resolve()
    return p.is_file() or p.is_dir()

Try / catch

try:
    files = collect_input_files(path)
except ValueError as e:
    if "must be a file or directory" in str(e):
        materialize_to_temp_file(path)  # e.g. read FIFO -> tmp .pdf, retry
    else:
        raise

Prevention

When it happens

Trigger: Passing /dev/stdin, a named pipe, a Unix socket path, or another non-regular file as input_path.

Common situations: Piping data via process substitution (e.g. <(curl ...)) which creates a FIFO; pointing at device nodes; exotic filesystems that report odd file types.

Related errors


AI-assisted analysis of opendatalab/MinerU@4fe4bde114 (2026-08-14). Data as JSON: /api/errors/0cce597377835091. Report an issue: GitHub.