fix(update): recover venv on Termux/proot when uv pip install fails#23579
Open
Endorpheen wants to merge 1 commit into
Open
fix(update): recover venv on Termux/proot when uv pip install fails#23579Endorpheen wants to merge 1 commit into
Endorpheen wants to merge 1 commit into
Conversation
Ali26hagr
approved these changes
May 19, 2026
e5c8f34 to
df15f33
Compare
On Termux/proot-distro, `uv pip install` can fail with ENOENT/EPERM when copying files into site-packages, leaving a broken venv with empty directories and missing __init__.py files. Subsequent installs then fail repeatedly because uv tries to write into the same broken paths. Changes: - Add proot-distro detection to _is_termux_startup_environment() via os.uname() release/version containing "PRoot" + /data/data/com.termux - Add _validate_and_fix_venv() which runs before dependency installation: verifies venv Python works, cleans empty dirs, removes broken packages, removes orphaned .dist-info, recreates venv if needed - Add helper functions: _is_empty_dir, _remove_empty_subdirs, _find_broken_packages, _find_orphaned_dist_info, _has_missing_core_deps, _recreate_venv - Add uv→pip fallback: if uv fails on Termux/proot, catch the error and fall back to regular pip instead of crashing the whole update - Use termux-all profile for pip fallback path on Termux/proot - No behavior change on regular Linux/macOS/Windows Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
df15f33 to
7c6c07f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Fixes
hermes updatefailures inside Termux/proot-distro environments whereuv pip installcannot reliably copy package files intosite-packages/, leaving the virtual environment partially broken.Related Issue
No existing issue found. Observed on Termux + proot-distro Ubuntu (aarch64).
Type of Change
Problem
On Termux/proot-distro,
hermes updatesuccessfully pulls code via git but crashes during dependency installation:Root causes:
uv pip installon proot-distro fails with ENOENT/EPERM file-copy errors due to proot filesystem translation limitations.pyfiles but missing__init__.pyuvruns see stale.dist-infometadata and skip reinstallation, believing packages are already installed_is_termux_env()only detected native Termux ($PREFIX), not proot-distro environments (Ubuntu kernel reports6.17.0-PRoot-Distro)pipwhenuvfails on Termux/prootAffected packages included
google_api_core,psutil,aiohttp,rich,anthropic, and ~200 others.Changes Made
hermes_cli/main.py— 287 lines added, 6 changedTermux/proot detection (
_is_termux_env)os.uname().releasecontaining"PRoot"+ presence of/data/data/com.termux, in addition to the existing$PREFIXcheckVenv validation (
_validate_and_fix_venv, new function)Runs before every dependency install during update:
.pyfiles but missing__init__.py(hallmark of partial uv copies).dist-infometadata (package removed but metadata remains, causing uv/pip to skip reinstallation)rich,httpx,openai,anthropic,psutil) and triggers full reinstall if any are missinguv-to-pip fallback
uv pip installraisesCalledProcessErroron Termux/proot, falls back topython -m pip install -e .[termux-all]CalledProcessErrorpropagates unchanged (no behavior change)Safe venv recreation (
_recreate_venv, new function)venv$HERMES_HOME(typically~/.hermes), not inside the venv, so this is safeHelper functions
_is_empty_dir/_remove_empty_subdirs— directory cleanup_find_broken_packages— detects packages with.pyfiles but no__init__.py_find_orphaned_dist_info— detects.dist-infowithout corresponding package directory_has_missing_core_deps— quick import smoke-test for critical packagesHow to Test
On Termux + proot-distro Ubuntu (aarch64):
On regular Linux/macOS (no regression):
hermes update # should work as before, using uvChecklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests pass — not run: pytest is broken in this venv (same uv partial-copy issue affecting_pytest/__init__.py)Documentation & Housekeeping
docs/, docstrings) — or N/A (all new functions have docstrings)cli-config.yaml.exampleif I added/changed config keys — N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — N/A_is_termux_env())Notes / Limitations
_is_termux_env()proot detection checksos.uname().releasefor the string"PRoot"and verifies/data/data/com.termuxexists. This is specific to proot-distro but should cover all Termux-based proot environments._has_missing_core_deps()probe list (rich,httpx,openai,anthropic,psutil) is a fixed set of critical packages. If the project's required dependencies change significantly, this list may need updating.ruffandpytestwere not available in the test environment (broken by the same uv issue this PR fixes). Python compilation check passed.