Solution:
Root Cause: Dangling Interpreter Symlinks When a Python virtual environment (
venv) is created on Linux or macOS, the
bin/python file is generated as a symbolic link pointing directly to the base system binary (e.g.,
/usr/bin/python3.10 or
/opt/homebrew/bin/python3.11). When the system updates Python (such as Homebrew upgrading Python from 3.11.4 to 3.12.0 or
apt removing the old minor package), the original binary path is removed. Consequently,
bin/python becomes a broken symlink, preventing activation scripts from locating a valid executable binary.
Diagnostic Verification: Navigate to your project virtual environment directory and run:
Copy
bash
ls -l .venv/bin/python*
Observe the output arrow (
->). If the target path points to a non-existent file, verify with
test -e:
Copy
bash
test -e .venv/bin/python || echo "Symlink is broken"
Step-by-Step Fix: 1 Re-link the Virtual Environment via In-Place Upgrade:
Run the native venv command with the --upgrade flag using the new Python binary path: Copy
bash
python3 --upgrade .venv
2 Manual Symlink Repair (Fallback):
If python3 --upgrade fails to resolve the binary pointer, forcefully update the internal symlinks: Copy
bash
cd .venv/bin
ln -sf $(which python3) python
ln -sf $(which python3) python3
cd ../..
3 Update pyvenv.cfg Base Path:
Open .venv/pyvenv.cfg in a text editor and update the home directive to reflect the new system Python directory: Copy
ini
home = /usr/bin
include-system-site-packages = false
version = 3.12.0
4 Verify Environment Execution:
Activate and verify binary resolution: Copy
bash
source .venv/bin/activate
which python
python --version
Prevention & Long-Term Monitoring: Avoid pointing project environments directly to system-managed Homebrew or apt interpreters; use pyenv to pin static local Python runtimes that remain unaffected by OS updates.