Skip to content
Latchkey

Python subprocess "FileNotFoundError: No such file or directory" in CI

subprocess could not find the program you asked it to run. The error names the executable, not a data file - either the binary isn’t installed/on PATH, or you passed a whole shell command string with shell=False.

What this error means

A subprocess.run/Popen call raises FileNotFoundError: [Errno 2] No such file or directory: '<cmd>'. The "file" in the message is the command itself, so Python couldn’t locate the executable to launch.

Python traceback
subprocess.run(["pdflatex", "doc.tex"])
# FileNotFoundError: [Errno 2] No such file or directory: 'pdflatex'

# or, passing a shell string without shell=True:
subprocess.run("ls -la /tmp")
# FileNotFoundError: [Errno 2] No such file or directory: 'ls -la /tmp'

Common causes

Executable not installed or not on PATH

The named command isn’t present in the CI image (or its directory isn’t on PATH), so the OS can’t exec it.

A shell command string with shell=False

Passing "ls -la /tmp" as a single arg without shell=True makes subprocess look for a literal executable named ls -la /tmp, which doesn’t exist.

How to fix it

Install the program (and verify PATH)

Terminal
# example: TeX for pdflatex
apt-get update && apt-get install -y texlive-latex-base
python -c "import shutil; print(shutil.which('pdflatex'))"

Pass a list, not a shell string

With shell=False (the default) pass argv as a list. Only use a string with shell=True.

Python
# correct
subprocess.run(["ls", "-la", "/tmp"])
# or, if you really need shell features
subprocess.run("ls -la /tmp", shell=True)

How to prevent it

  • Install required external programs in the runner image.
  • Pass argv as a list to subprocess unless you explicitly need a shell.
  • Probe with shutil.which and fail early with a clear message.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →