I was setting up a new Python project with direnv to manage environment variables. Suddenly python wasn’t found, even though it was definitely installed. Here’s what happened and how I fixed it.
The problem Link to heading
I’d been using direnv happily for months, managing API keys and secrets per project. Then I added a custom PATH in my .envrc and broke everything:
# This was the problem
export PATH=/some/custom/path
Running which python returned nothing. Even python3 was gone. My shell couldn’t find Python at all.
Debugging the issue Link to heading
First, check what direnv is doing:
direnv status
This shows you:
- Whether direnv is loaded for the current directory
- What
.envrcfile it’s using - If there are any errors
In my case, it showed PATH had been completely replaced, not augmented.
My .envrc setup Link to heading
Here’s a proper .envrc that doesn’t break Python:
# Load Python virtual environment
layout python3
# Or if using uv (which I prefer now)
source .venv/bin/activate
# Add custom paths without clobbering existing PATH
PATH_add bin
PATH_add scripts
# Environment variables
export DATABASE_URL="postgresql://localhost/mydb"
export DEBUG=true
export API_KEY=secret-key-here
The key difference:
# Bad - replaces entire PATH
PATH=/some/path
# Good - appends to PATH
PATH_add /some/path
direnv + pyenv + uv interaction Link to heading
These three tools work well together if you load them in the right order. In ~/.zshrc:
# pyenv first (manages Python versions)
eval "$(pyenv init -)"
# direnv second (manages per-project env)
eval "$(direnv hook zsh)"
# uv doesn't need shell integration
When entering a project directory:
pyenvsets the Python version (from.python-version)direnvloads.envrc(which might activate a venv)uvuses whatever Python is active
One gotcha: if you use layout python3 in .envrc, it will create a virtualenv using the Python on your PATH. Make sure that’s the right version before running direnv allow.
The fix Link to heading
After editing .envrc, you must allow it:
direnv allow
Verify Python is found:
which python
# Should show: /path/to/your/project/.venv/bin/python
python --version
# Should match what you expect
When direnv is the right tool Link to heading
direnv works well for:
- Project-specific environment variables (API keys, database URLs)
- Automatically activating virtual environments when I
cdinto a project - Setting up development vs production configs (via different
.envrcfiles)
direnv is not ideal for:
- Secrets that need rotation (use a secrets manager)
- System-wide PATH changes (put those in your shell config)
- Temporary variables (just
exportthem in your current shell)
The brilliant thing about direnv is that it automatically unloads when you leave the directory. No more forgetting to deactivate virtual environments.
Further reading Link to heading
- direnv wiki
- direnv stdlib functions (explains
layout python3,PATH_add, etc.) - pyenv documentation
- uv documentation