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:
bash
ls -l .venv/bin/python*
Observe the output arrow (
->). If the target path points to a non-existent file, verify with
test -e:
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: bash
python3 --upgrade .venv
2.
Manual Symlink Repair (Fallback):
If python3 --upgrade fails to resolve the binary pointer, forcefully update the internal symlinks: 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: ini
home = /usr/bin
include-system-site-packages = false
version = 3.12.0
4.
Verify Environment Execution:
Activate and verify binary resolution: 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.