Skip to content
Latchkey

Python PYTHONPATH Not Set in CI - First-Party Imports Fail

Code that imports your own packages by running from the repo root works locally, but CI may run from a different directory or a fresh shell with no PYTHONPATH. The interpreter then cannot find your top-level package.

What this error means

A first-party import like from src.app import main raises ModuleNotFoundError in CI even though the file is present. Adding PYTHONPATH=. (or src) to the step fixes it, confirming the path was the issue.

Python traceback
Traceback (most recent call last):
  File "scripts/run.py", line 1, in <module>
    from src.app import main
ModuleNotFoundError: No module named 'src'

Common causes

Relying on cwd-based import resolution

Python adds the script’s directory (not the repo root) to sys.path. Imports that assume the repo root is on the path break when invoked from elsewhere.

PYTHONPATH not exported in the step

Each CI step is a fresh shell with no inherited PYTHONPATH. A working-locally export does not carry into the CI job.

How to fix it

Install the project instead of using PYTHONPATH

The durable fix is an editable install so the package is importable regardless of cwd.

Terminal
pip install -e .
python -c "import app"   # resolves from site-packages

Set PYTHONPATH for the job when needed

For scripts not packaged, export PYTHONPATH for the whole job.

.github/workflows/ci.yml
- run: echo "PYTHONPATH=$PWD" >> "$GITHUB_ENV"
- run: python scripts/run.py

How to prevent it

  • Package the project and pip install -e . so imports are stable.
  • Adopt a clear src-layout declared in pyproject.toml.
  • Avoid relying on the repo root being implicitly on sys.path.

Related guides

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