hermes - ✅(Solved) Fix Gateway leaks VIRTUAL_ENV into subprocesses; agent's `uv sync` in any project bricks Hermes' own venv [1 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#23473Fetched 2026-05-11 03:29:18
View on GitHub
Comments
0
Participants
1
Timeline
6
Reactions
0
Author
Participants
Timeline (top)
labeled ×5cross-referenced ×1

The Hermes gateway leaks its own VIRTUAL_ENV into every terminal subprocess. If the agent runs uv sync, uv pip install, poetry install, or pip install in any project directory other than its own, those tools treat Hermes' venv as the active install target and rebuild it against the user's pyproject.toml — wiping every Hermes runtime dependency and bricking the gateway on the next restart.

Root Cause

hermes_cli/gateway.py emits Environment="VIRTUAL_ENV={venv_dir}" in three places:

  • line 2164 — system unit template
  • line 2199 — user unit template
  • line 2807 — launchd plist template

The gateway needs VIRTUAL_ENV set for its own process resolution, but nothing scrubs it when spawning terminal subprocesses. uv (and poetry, pip --user, pipenv) treat inherited VIRTUAL_ENV as an implicit --target.

Fix Action

Fix / Workaround

Workaround until the fix lands

PR fix notes

PR #23474: fix(terminal): strip VIRTUAL_ENV from agent subprocess envs

Description (problem / solution / changelog)

Fixes #23473.

Problem

The gateway systemd unit sets VIRTUAL_ENV=<hermes-venv> so the gateway process can find its own .venv. That variable then leaks into every terminal subprocess Hermes spawns.

If the agent runs uv sync, uv pip install, poetry install, or pip install in any project directory other than Hermes' own, those tools see VIRTUAL_ENV pointing at Hermes' venv and treat it as the active install target. They rebuild it against the user's pyproject.toml, wipe every Hermes runtime dependency, and the gateway fails on the next restart.

Reproduced in the wild: cd ~/code/some-project && uv sync wiped ~/.hermes/hermes-agent/venv (Python 3.11 → 3.12, every dep gone) mid-conversation. Full repro and root-cause analysis in #23473.

Fix

Scrub at the subprocess-env boundary in tools/environments/local.py. Add VIRTUAL_ENV and the related package-manager activation markers to _HERMES_PROVIDER_ENV_BLOCKLIST:

  • VIRTUAL_ENV
  • VIRTUAL_ENV_PROMPT
  • UV_PROJECT_ENVIRONMENT
  • POETRY_ACTIVE
  • PIPENV_ACTIVE
  • CONDA_PREFIX
  • CONDA_DEFAULT_ENV

The gateway still receives VIRTUAL_ENV from its unit file — it just stops there.

Why not UnsetEnvironment= in the systemd unit?

That removes VIRTUAL_ENV from the gateway's own environment, which the unit specifically sets for the gateway process. We need it set for the gateway and unset for children of the gateway. The subprocess-env scrub is the right layer.

Opt-out

Users who genuinely want their terminal tools to run inside Hermes' venv can add VIRTUAL_ENV to tools.env_passthrough in config.yaml. The existing passthrough mechanism in tools/env_passthrough.py already handles this — no new plumbing needed.

Tests

Added a TestVirtualEnvIsBlocked class in tests/tools/test_local_env_blocklist.py:

  • test_virtual_env_is_blocked — membership in the blocklist
  • test_related_venv_markers_are_blocked — covers the full set of package-manager markers
  • test_sanitize_strips_virtual_env — end-to-end: _sanitize_subprocess_env strips the var

All 38 tests in tests/tools/test_local_env_blocklist.py + tests/tools/test_env_passthrough.py pass locally.

Out of scope (deferred)

  • Startup sys.prefix / VIRTUAL_ENV self-check in the gateway — would catch leftover broken venvs from earlier clobbering. Belongs on the hermes doctor work in #8946.
  • Touching the systemd / launchd unit templates in hermes_cli/gateway.py — not needed once the subprocess scrub is in place.

Changed files

  • tests/tools/test_local_env_blocklist.py (modified, +43/-0)
  • tools/environments/local.py (modified, +15/-0)

Code Example

# any session where the gateway is running as a systemd service:
cd ~/code/some-other-project    # has its own pyproject.toml
uv sync                          # uv sees VIRTUAL_ENV=~/.hermes/hermes-agent/venv
                                 # and reinstalls THAT venv against this project's deps
sudo systemctl restart hermes-gateway  # crashes — Hermes deps gone

---

# Add to ~/.config/systemd/user/hermes-gateway.service.d/no-venv-leak.conf
[Service]
UnsetEnvironment=VIRTUAL_ENV
RAW_BUFFERClick to expand / collapse

Summary

The Hermes gateway leaks its own VIRTUAL_ENV into every terminal subprocess. If the agent runs uv sync, uv pip install, poetry install, or pip install in any project directory other than its own, those tools treat Hermes' venv as the active install target and rebuild it against the user's pyproject.toml — wiping every Hermes runtime dependency and bricking the gateway on the next restart.

Reproducer

# any session where the gateway is running as a systemd service:
cd ~/code/some-other-project    # has its own pyproject.toml
uv sync                          # uv sees VIRTUAL_ENV=~/.hermes/hermes-agent/venv
                                 # and reinstalls THAT venv against this project's deps
sudo systemctl restart hermes-gateway  # crashes — Hermes deps gone

What happened in my case

Mid-conversation the agent ran uv sync inside ~/code/fb-mcp. uv honored the inherited VIRTUAL_ENV (set by the gateway systemd unit at hermes_cli/gateway.py:2164 / :2199), reinstalled ~/.hermes/hermes-agent/venv against fb-mcp/pyproject.toml, replaced Python 3.11 with 3.12, and dropped every Hermes dependency. Next gateway restart died with ModuleNotFoundError.

Diagnostic artifacts (Python before/after, dep list before/after, the offending uv invocation) are reproducible by setting VIRTUAL_ENV=/path/to/hermes/venv in any shell and running uv sync in any other project.

Root cause

hermes_cli/gateway.py emits Environment="VIRTUAL_ENV={venv_dir}" in three places:

  • line 2164 — system unit template
  • line 2199 — user unit template
  • line 2807 — launchd plist template

The gateway needs VIRTUAL_ENV set for its own process resolution, but nothing scrubs it when spawning terminal subprocesses. uv (and poetry, pip --user, pipenv) treat inherited VIRTUAL_ENV as an implicit --target.

Proposed fix

Scrub at the subprocess-env boundary, not the unit boundary. Add VIRTUAL_ENV and the other package-manager activation markers (VIRTUAL_ENV_PROMPT, UV_PROJECT_ENVIRONMENT, POETRY_ACTIVE, PIPENV_ACTIVE, CONDA_PREFIX, CONDA_DEFAULT_ENV) to _HERMES_PROVIDER_ENV_BLOCKLIST in tools/environments/local.py. Users who actually want their tools to run inside Hermes' venv can opt back in via tools.env_passthrough.

PR: #PRNUM_HERE

Related

  • #1264 — stripped provider secrets from subprocess env but didn't touch VIRTUAL_ENV
  • #22054 — open: PATH injection from venv (adjacent symptom)
  • #21788 — closed: .venv vs venv confusion
  • #8946 — open: hermes doctor feature; a startup sys.prefix self-check would catch this class of failure earlier

Workaround until the fix lands

# Add to ~/.config/systemd/user/hermes-gateway.service.d/no-venv-leak.conf
[Service]
UnsetEnvironment=VIRTUAL_ENV

Note this only protects against the gateway itself leaking it — it does not protect terminal subprocesses that read VIRTUAL_ENV from the gateway's own environment. The real fix is the subprocess scrub.

Severity

High. Corrupts Hermes' own installation. Recovery requires a manual uv sync --python 3.11 --extra messaging --extra mcp --extra web from outside the agent (because the agent is dead). User has no warning — the symptom is "gateway crashed on restart" hours later.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - ✅(Solved) Fix Gateway leaks VIRTUAL_ENV into subprocesses; agent's `uv sync` in any project bricks Hermes' own venv [1 pull requests, 1 participants]