ocrmypdf/OCRmyPDF · error · MissingDependencyError

Ran program '{program}' but it exited with an error: {e.outp

Error message

Ran program '{program}' but it exited with an error:
{e.output}

What it means

The version-check subprocess ran but exited non-zero, so the tool exists but failed when asked for its version. The tool's output is embedded in the message.

Source

Thrown at src/ocrmypdf/subprocess/_version.py:58

    try:
        proc = _sp.run(
            args_prog,
            close_fds=True,
            text=True,
            stdout=PIPE,
            stderr=STDOUT,
            check=True,
            env=env,
        )
        output: str = proc.stdout
    except FileNotFoundError as e:
        raise MissingDependencyError(
            f"Could not find program '{program}' on the PATH"
        ) from e
    except CalledProcessError as e:
        if e.returncode != 0:
            log.exception(e)
            raise MissingDependencyError(
                f"Ran program '{program}' but it exited with an error:\n{e.output}"
            ) from e
        raise MissingDependencyError(
            f"Could not find program '{program}' on the PATH"
        ) from e

    # Some tools (e.g. veraPDF launched on a recent JDK) print warnings before
    # the version line, so scan each line rather than only the start of output.
    version = None
    for line in output.splitlines():
        match = re.match(regex, line.strip())
        if match:
            version = match.group(1)
            break
    if version is None:
        raise MissingDependencyError(
            f"The program '{program}' did not report its version. "
            f"Message was:\n{output}"

View on GitHub (pinned to 5074a0b0e1)

Solutions

  1. Run the exact failing command manually (e.g. `qpdf --version`) to see the real error
  2. Fix the underlying crash: reinstall the package or install missing shared libraries (ldd /usr/bin/tesseract)
  3. If it's a custom plugin tool, ensure it supports the version flag passed to get_version

Example fix

# before
v = get_version('mytool', args=['--version'], regex=r'mytool v(.*)')
# after
import subprocess
out = subprocess.run(['mytool', '--version'], capture_output=True, text=True)
# inspect out.returncode/out.stderr, fix install, then call get_version
Defensive patterns

Strategy: try-catch

Validate before calling

import subprocess\nr = subprocess.run([program, '--version'], capture_output=True, text=True)\nassert r.returncode == 0, r.stderr

Try / catch

try:\n    v = get_version(program, regex=...)\nexcept MissingDependencyError as e:\n    if 'exited with an error' in str(e):\n        fix_tool_install(program)  # reinstall / install libs\n    raise

Prevention

When it happens

Trigger: get_version(program) where Popen succeeds but the process exits with returncode != 0 — e.g. a broken install, missing shared libraries, or a tool that errors on the version flag used.

Common situations: Half-installed packages, missing runtime libs (libtesseract, ghostscript libs), sandboxed environments where the binary crashes, or a wrong --version argument expectation for a custom tool.

Related errors


AI-assisted analysis of ocrmypdf/OCRmyPDF@5074a0b0e1 (2026-08-27). Data as JSON: /api/errors/2382b175c2347ad2. Report an issue: GitHub.