Repository navigation
Conversation
…rgv leads with the base interpreter A uv venv's Scripts\python.exe is a trampoline: a RUNNING gateway shows argv[0] = the base CPython, so the updater's captured-argv respawn replayed the base interpreter with no venv binding and died at 'import yaml' (NousResearch#106489). Map that interpreter back to the venv launcher via pyvenv.cfg home= and set __PYVENV_LAUNCHER__ in the respawn overlay as belt-and-braces. Fixes NousResearch#106489
1 task done
This branch has not been deployed
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.
Problem
On Windows with a uv-managed venv,
venv\Scripts\python.exeis a trampoline: it re-execs the base CPython, so a running gateway showsargv[0] = ...\uv\python\cpython-3.11-...\python.exe, with the venv shim only as its parent. The updater's pause/relaunch machinery snapshots that live argv and replays it verbatim on respawn, butwindowless_gateway_restart_spec()passes a console interpreter through unchanged and the respawn env overlay (HERMES_HOME/VIRTUAL_ENV/PYTHONPATH) never sets__PYVENV_LAUNCHER__.The respawned base interpreter imports
hermes_clifromPYTHONPATHbut has no venv site-packages and dies at the first import:The 30 s liveness poll then fails (
Windows gateway restart could not be verified — no stable gateway process appeared after relaunch), the update exits 1, and the gateway stays down — the desktop app is left showing "Content unavailable" on127.0.0.1:12509until a manualhermes gateway restart.Observed in the wild on v0.21.4 (2026-09-25): after a
git fetchnetwork timeout aborted the update, both the in-process resume and the atexit safety-net respawned the gateway with the base interpreter;logs/gateway-stdio.logcaptured exactly the traceback above, once per attempt.Fix
_resolve_detached_python(): when the incoming interpreter is the base interpreter of the venv this process runs from — matched againstpyvenv.cfg'shome=(BOM-tolerant read, case-insensitivenormcasecompare) — rewrite it to the venv's consolepython.exe. Callers that already pass the venv python are unaffected (its parent directory never equals the pyvenvhome=); unrelated interpreters are left untouched. As a side effect,VIRTUAL_ENVstops pointing at the uv install dir on this path.windowless_gateway_restart_spec(): when the resolved respawn interpreter belongs to this checkout's venv, add__PYVENV_LAUNCHER__=<venv python.exe>to the env overlay — belt-and-braces per the issue's suggestion, so a base-interpreter argv still resolves venv site-packages even if the argv rewrite is ever bypassed.Scope note: point 3 of #106489 (the atexit double-fire) is already resolved by #116804 — this PR is strictly points 1 + 2.
cc @licat2023 — the issue notes a local patch was ready; if yours is still in flight, happy to stand down or fold the approaches together.
Verification
tests/hermes_cli/test_gateway_windows.py:python.exeandpythonw.exespellings) respawns on the venv launcher, with the correctVIRTUAL_ENVand__PYVENV_LAUNCHER__;sys.prefix == sys.base_prefix) sets no binding;pyvenv.cfghome=match, mismatch, missing launcher, missing cfg.pytest tests/hermes_cli/test_gateway_windows.py tests/hermes_cli/test_update_gateway_launcher_refresh.py tests/hermes_cli/test_windows_update_restart_reconciliation.py tests/hermes_cli/test_windows_gateway_cold_start_desktop_lifecycle.py -q→ 43 passed, 1 pre-existing failure (test_exec_schtasks_round_trips_non_ascii_task_argument_live— liveschtasks /Createis denied on the reporting host; it fails identically on a clean tree).ruff check(pinned 0.15.10) clean;ruff formatintroduces no changes to the added lines (both files carry pre-existing format drift in untouched regions);scripts/check-windows-footguns.pyclean on the changed files (the helper readspyvenv.cfgwithutf-8-sigper the BOM policy).Fixes #106489