fix(gateway): keep venv python symlink unresolved when remapping paths for systemd unit - #7735
Closed
akhater wants to merge 1 commit into
Closed
Conversation
_remap_path_for_user was calling .resolve() on the Python path, which followed venv/bin/python into the base interpreter. On uv-managed venvs this swaps the systemd ExecStart to a bare Python that has none of the venv's site-packages, so the service crashes on first import. Classical python -m venv installs were unaffected by accident: the resolved target /usr/bin/python3.x lives outside $HOME so the path-remap branch was skipped and the system Python's packages silently worked. Remove .resolve() calls on both current_home and the path; use .expanduser() for lexical tilde expansion only. The function does lexical prefix substitution, which is all it needs to do for its actual purpose (remapping /root/.hermes -> /home/<user>/.hermes when installing system services as root for a different user). Repro: on a uv-managed venv install, `sudo hermes gateway install --system` writes ExecStart=.../uv/python/cpython-3.11.15-.../bin/python3.11 instead of .../hermes-agent/venv/bin/python, and the service crashes on ModuleNotFoundError: yaml. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
4 tasks
Contributor
Contributor
Author
|
Thanks @teknium1! |
This was referenced Apr 13, 2026
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.
Summary
hermes gateway install --systemwrites a systemd unit whoseExecStart=points at the resolved target ofvenv/bin/pythoninstead of the symlink itself. On uv-managed venvs (wherevenv/bin/pythonis a symlink into~/.local/share/uv/python/...) this swaps the unit's Python to the bare base interpreter, which has none of the venv's site-packages. The service crashes on its firstimport yamland loops forever onRestart=on-failure.Classical
python -m venvinstalls were unaffected by accident — the venv'sbin/pythonsymlinks to/usr/bin/python3.x, which is outside$HOME, so therelative_to(Path.home())path was skipped and the system Python (which hasyamlinstalled globally) silently worked.Repro
On a uv-managed venv (i.e.
~/.hermes/hermes-agent/venv/bin/pythonis a symlink into~/.local/share/uv/python/cpython-X.Y.Z-linux-x86_64-gnu/bin/python3.x):Observed:
The
hermes gateway start --systemwrapper prints✓ System service startedbecausesystemctl startreturned 0 — systemd accepted the start request. It does not verify the process survived past the first second.Root cause
hermes_cli/gateway.py:_remap_path_for_userwas doing:The function's documented purpose is lexical prefix substitution:
i.e. remapping
/root/.hermesto/home/<user>/.hermeswhen installing a system service as root for a target user. Symlink resolution is an unrelated operation that happens to work for classical venvs (because/usr/bin/python3.xescapes$HOMEand falls through theexcept ValueErrorbranch to return the system Python) and silently breaks uv-managed venvs (where the resolved target is still under$HOME, gets the home-prefix remap applied, and lands on a bare Python outside the venv'ssite-packages).Fix
Drop the
.resolve()calls. Use.expanduser()for lexical~expansion only.Backward compatibility:
venv/bin/pythontypically lives under$HOME/<project>/venv/bin/python, which is already underPath.home()— therelative_tobranch was taken before and is still taken now, just without following symlinks. Either way, invokingvenv/bin/pythonactivates the venv's site-packages.alice): still works. The lexical prefix swap is the entire point of the function and is preserved./opt/hermes): still returned unchanged — therelative_tocall throwsValueErrorand the fallback branch returns the unmodified path.Test plan
systemctl is-activereportsactive, noModuleNotFoundErrorin journalctl/home/<target>prefix, unit file is in/etc/systemd/system/, start succeeds/opt/hermes-style install (path outside$HOME): assert path is returned unchanged