Skip to content
Latchkey

Python "subprocess.CalledProcessError: returned non-zero exit status" in CI

subprocess.run(..., check=True) and check_call/check_output raise CalledProcessError when the child process exits non-zero. The exception carries the exit code but, by default, not the captured output.

What this error means

A step fails with "subprocess.CalledProcessError: Command '[...]' returned non-zero exit status 1." with no detail about why the child failed.

python
subprocess.CalledProcessError: Command '['git', 'describe']' returned non-zero exit status 128.

Common causes

The invoked command genuinely failed

The child tool errored (missing arg, missing repo state, missing file) and returned non-zero.

The tool is missing or the environment differs in CI

A binary present locally is not installed on the runner, or its inputs differ.

How to fix it

Capture and surface the child output

  1. Pass capture_output=True, text=True so stdout/stderr are available.
  2. Catch CalledProcessError and log e.stdout and e.stderr to see the real cause.
  3. Fix the underlying command, or ensure the tool is installed in CI.
Python
import subprocess

try:
    subprocess.run(cmd, check=True, capture_output=True, text=True)
except subprocess.CalledProcessError as e:
    raise RuntimeError(f"{cmd} failed ({e.returncode}): {e.stderr}") from e

How to prevent it

  • Always capture child output when using check=True.
  • Ensure required binaries are installed in the CI image.
  • Log the full command and its stderr on failure.

Related guides

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