Gateway systemd service Python environment path issues

NousResearch/hermes-agent · cluster 7976 · environments

Data as of

Nothing open on GitHub. Fix merged in #8861. Check it covers your case.

The short answer

0open issues
0open PRs
15items grouped
Known?
Yes. 15 related items grouped here, 8 issues already closed.
Fix event
A fix was merged to main in PR #8861. Check it covers your case. No release data is tracked.
Tracker
The maintainers' tracker marks this partially resolved, deciding PR #10093. That is separate from the fix event.
Still open
Nothing open on GitHub.

Most items concern the gateway's systemd service unit pointing to the wrong Python executable—system Python, hardcoded paths, or uv Python instead of the virtualenv's Python. A handful of adjacent items touch Nix/Hermes wrapper handling, startup exit codes, and minor unrelated fixes bundled into the same PRs.

Open issues0

No open issues.

Open PRs0

No open pull requests.

Fixes on record

Merged to main. A stamp counts the issues a fix is linked to.

  • #8861 fix(gateway): keep venv python symlink unresolved in systemd unit

    merged to main

    files: hermes_cli/gateway.py

    Show the diff
    • hermes_cli/gateway.py
      @@ -768,14 +768,22 @@ def _remap_path_for_user(path: str, target_home_dir: str) -> str:
       
             /root/.hermes/hermes-agent  -> /home/alice/.hermes/hermes-agent
             /opt/hermes                 -> /opt/hermes  (kept as-is)
      +
      +    Note: this function intentionally does NOT resolve symlinks. A venv's
      +    ``bin/python`` is typically a symlink to the base interpreter (e.g. a
      +    uv-managed CPython at ``~/.local/share/uv/python/.../python3.11``);
      +    resolving that symlink swaps the unit's ``ExecStart`` to a bare Python
      +    that has none of the venv's site-packages, so the service crashes on
      +    the first ``import``. Keep the symlinked path so the venv activates
      +    its own environment. Lexical expansion only via ``expanduser``.
           """
      -    current_home = Path.home().resolve()
      -    resolved = Path(path).resolve()
      +    current_home = Path.home()
      +    p = Path(path).expanduser()
           try:
      -        relative = resolved.relative_to(current_home)
      +        relative = p.relative_to(current_home)
               return str(Path(target_home_dir) / relative)
           except ValueError:
      -        return str(resolved)
      +        return str(p)
       
       
       def _hermes_home_for_target_user(target_home_dir: str) -> str:
  • #10093 fix: compression model falls back to main model on permanent 503/404 (#8620)

    merged to main

    files: agent/context_compressor.py

    Show the diff
    • agent/context_compressor.py
      @@ -693,6 +693,7 @@ def _generate_summary(self, turns_to_summarize: List[Dict[str, Any]], focus_topi
                   # Store for iterative updates on next compaction
                   self._previous_summary = summary
                   self._summary_failure_cooldown_until = 0.0
      +            self._summary_model_fallen_back = False
                   return self._with_summary_prefix(summary)
               except RuntimeError:
                   # No provider configured — long cooldown, unlikely to self-resolve
      @@ -703,6 +704,34 @@ def _generate_summary(self, turns_to_summarize: List[Dict[str, Any]], focus_topi
                                   _SUMMARY_FAILURE_COOLDOWN_SECONDS)
                   return None
               except Exception as e:
      +            # If the summary model is different from the main model and the
      +            # error looks permanent (model not found, 503, 404), fall back to
      +            # using the main model instead of entering cooldown that leaves
      +            # context growing unbounded.  (#8620 sub-issue 4)
      +            _status = getattr(e, "status_code", None) or getattr(getattr(e, "response", None), "status_code", None)
      +            _err_str = str(e).lower()
      +            _is_model_not_found = (
      +                _status in (404, 503)
      +                or "model_not_found" in _err_str
      +                or "does not exist" in _err_str
      +                or "no available channel" in _err_str
      +            )
      +            if (
      +                _is_model_not_found
      +                and self.summary_model
      +                and self.summary_model != self.model
      +                and not getattr(self, "_summary_model_fallen_back", False)
      +            ):
      +                self._summary_model_fallen_back = True
      +                logging.warning(
      +                    "Summary model '%s' not available (%s). "
      +                    "Falling back to main model '%s' for compression.",
      +                    self.summary_model, e, self.model,
      +                )
      +                self.summary_model = ""  # empty = use main model
      +                self._summary_failure_cooldown_until = 0.0  # no cooldown
      +                return self._generate_summary(messages, summary_budget)  # retry immediately
      +
                   # Transient errors (timeout, rate limit, network) — shorter cooldown
                   _transient_cooldown = 60
                   self._summary_failure_cooldown_until = time.monotonic() + _transient_cooldown

5 PRs closed without merging

From the close comments: done elsewhere 3 · duplicate 2

  • #7985 fix(gateway): fall back to python3 when venv lacks bare python symlink · done elsewhere → #8861, #7735
  • #8522 fix: preserve venv symlink in systemd service ExecStart path · done elsewhere → #8861, #7735
  • #9230 fix(gateway): use venv Python for systemd ExecStart instead of sys.executable (#9201) · done elsewhere → 73ed09e, #9629
  • #9629 fix(gateway): systemd Python path fallback · duplicate → #9230
  • #48086 fix(gateway): use hermes wrapper as systemd ExecStart on Nix installs (#48071) · duplicate → #48071, #33663
Closed issues · 8
  • Closed#7976[Bug]: gateway install --system ExecStart skips project venv
  • Closed#8475[Setup]: gateway startup seems to fail with an error exit code
  • Closed#8519Systemd service uses resolved Python path instead of venv symlink, breaking module imports
  • Closed#8620Gateway restart failures: wrong Python env in systemd, immediate exit after --replace, context_length not read, compression model 503
  • Closed#9013gateway install --system uses system Python instead of venv Python in ExecStart
  • Closed#9021PR: fix system service venv python path (Issue #9013)
  • Closed#9201[Bug]: systemd system service fails on boot: ExecStart uses uv Python instead of venv Python
  • Closed#48071[Bug]: Nix level-1 gateway install generates systemd unit that bypasses Hermes wrapper
How this cluster was grouped
  • Link evidence (partly structural links): some members are connected by structural evidence (shared changed files, or a closing/superseded reference); the rest are joined by an automated relevance judgement over their text.
  • Members outside that structural core may belong to a different underlying problem.
  • Pairwise link density 0.12: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. 1.00 means every pair is linked.

Pick up a Lab task

Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.

Open the Lab

At a glance

Subsystem
environments
Merged PRs
#8861, #10093
Closed issues
8
Attempts
5 PRs closed without merging
Fix link checked
15 Apr 2026. This confirmation is old and may be out of date (a revert or reopen would not have invalidated it here); re-verify.

For your agent

The same facts, typed.