hermes - ✅(Solved) Fix hermes doctor / browser tool can't find Node when launched non-interactively (mise/asdf/nvm shims, Homebrew) [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#18158Fetched 2026-05-01 05:53:39
View on GitHub
Comments
0
Participants
1
Timeline
5
Reactions
0
Author
Participants
Timeline (top)
labeled ×4cross-referenced ×1

Fix Action

Fix / Workaround

I have a working patch with tests and will open a PR.

PR fix notes

PR #18159: fix(doctor,browser): centralize tool PATH fallbacks (mise/asdf/nvm/Homebrew)

Description (problem / solution / changelog)

Fixes #18158

Summary

hermes doctor and tools/browser_tool independently need a sane PATH for finding Node, npm, agent-browser, and other CLI tools when Hermes is launched from a non-interactive process manager (launchd, systemd user services, dashboards, IDE integrations, cron). In those environments the user's shell init is not sourced, so version-manager shims (mise / asdf / nvm) and Homebrew locations are missing from PATH even when the tools are installed and work fine in an interactive shell.

This PR introduces hermes_cli/path_env.py and wires both call sites through it so they agree on the same fallback set.

What's in the patch

hermes_cli/path_env.py — three small helpers:

  • common_tool_path_dirs(existing_only=True) — ordered fallback PATH directories: user-level shims first (~/.local/bin, ~/.local/share/mise/shims, ~/.asdf/shims, ~/.nvm/versions/node/*/bin, ~/.bun/bin), then platform locations (/opt/homebrew/{bin,sbin}, Termux dirs, /usr/local/{bin,sbin}, /usr/{bin,sbin}, /{bin,sbin}). Filters to existing dirs by default.
  • merge_common_tool_path(existing_path=None, prepend=False) — merge fallbacks into a PATH string while preserving an explicitly configured PATH by default; opt-in to prepend.
  • ensure_common_tool_paths(prepend=False) — update os.environ['PATH'] in place.

Wires it in:

  • hermes_cli/doctor.py — call ensure_common_tool_paths() right before the External Tools check so version-manager shims become visible to shutil.which() lookups.
  • tools/browser_tool.py — derive _SANE_PATH / _SANE_PATH_DIRS from common_tool_path_dirs(existing_only=False) so doctor and the browser tool agree on the same fallback set.

Behavior change

  • Users with mise/asdf/nvm-managed Node now see ✓ Node.js and ✓ agent-browser from hermes doctor even when Hermes is launched from a non-interactive process manager — without needing an external wrapper script around the hermes entrypoint.
  • tools/browser_tool picks up the same set, so the browser subprocess sees the same tool directories doctor verified.
  • Existing PATH entries keep priority — fallbacks are appended by default, with an opt-in prepend=True for callers that need fallbacks to win (e.g. browser command execution).

Tests

New tests: tests/hermes_cli/test_path_env.py covers helper behaviour: version-manager dirs, Homebrew/Termux statics, dedupe, append vs prepend, and os.environ['PATH'] mutation.

Updated tests:

  • tests/hermes_cli/test_doctor.py::test_run_doctor_sets_interactive_env_for_tool_checks — also asserts that doctor invokes the path helper.
  • tests/tools/test_browser_homebrew_paths.py::TestSanePath — adds assertions that _SANE_PATH includes mise/asdf shims (still covers Homebrew and standard dirs).
$ python -m pytest tests/hermes_cli/test_path_env.py \
                   tests/hermes_cli/test_doctor.py::test_run_doctor_sets_interactive_env_for_tool_checks \
                   tests/tools/test_browser_homebrew_paths.py -o 'addopts=' -q
29 passed

Risk / scope

Small surface, no breaking changes:

  • New helper module with three functions and unit tests
  • One new call in hermes_cli/doctor.py (idempotent)
  • tools/browser_tool switches from a hand-maintained tuple to the helper output, with the same Homebrew/Termux/FHS coverage plus the new shim dirs
  • No new dependencies; everything is stdlib os / pathlib.

Changed files

  • hermes_cli/doctor.py (modified, +7/-0)
  • hermes_cli/path_env.py (added, +118/-0)
  • tests/hermes_cli/test_doctor.py (modified, +6/-0)
  • tests/hermes_cli/test_path_env.py (added, +79/-0)
  • tests/tools/test_browser_homebrew_paths.py (modified, +6/-0)
  • tools/browser_tool.py (modified, +4/-14)

Code Example

Node.js (not found in PATH)
   ✗ agent-browser (Node.js) system dependency not met
RAW_BUFFERClick to expand / collapse

hermes doctor and the browser tool can't find Node/Homebrew when launched from a non-interactive process manager

Bug Description

hermes doctor reports Node.js not found and agent-browser (Node.js) system dependency not met whenever Hermes is run from a launcher that does not source the user's interactive shell init (launchd, systemd user services, dashboard actions, IDE integrations, cron, some terminal multiplexers).

The same install works perfectly from an interactive shell — the difference is that mise, asdf, nvm, and Homebrew all rely on shell init to put their shims/bins on PATH, and a non-interactive Python launcher inherits whatever sparse PATH the process manager handed down.

tools/browser_tool.py already has a hand-maintained _SANE_PATH_DIRS for the same problem (Termux, Homebrew, FHS dirs), but hermes_cli/doctor.py doesn't use anything similar — and neither covers user-level version managers like mise/asdf/nvm. As a result the two diverge, and doctor reports failures that the browser tool itself wouldn't actually hit at runtime.

Steps to reproduce

  1. macOS, Node installed via mise (mise use --global node@24 or similar). Confirm command -v node works in interactive zsh.
  2. Run Hermes from any non-interactive launcher (launchd/LaunchAgent, dashboard quick-action, env -i, a non-login shell, etc.) and call hermes doctor.
  3. External Tools section reports:
    ✗ Node.js (not found in PATH)
    ✗ agent-browser (Node.js) system dependency not met
    even though ~/.local/share/mise/shims/node -v returns the installed version.

Expected behavior

hermes doctor and tools/browser_tool should both fall back to a common, well-known set of tool directories that includes:

  • User-level shims: ~/.local/bin, ~/.local/share/mise/shims, ~/.asdf/shims, ~/.nvm/versions/node/*/bin, ~/.bun/bin
  • Platform locations: /opt/homebrew/{bin,sbin}, Termux dirs, /usr/local/{bin,sbin}, /usr/{bin,sbin}, /{bin,sbin}

…so non-interactive launches behave consistently with what the user sees in an interactive shell.

Actual behavior

  • hermes doctor reports Node missing whenever launched non-interactively, regardless of mise/asdf/nvm.
  • tools/browser_tool._SANE_PATH_DIRS covers Homebrew and Termux but not version-manager shims, so users end up writing external wrappers around the hermes entrypoint just to make hermes doctor agree with reality.

Proposed fix

Centralize the fallback list in a small helper (e.g. hermes_cli/path_env.py) with three functions:

  • common_tool_path_dirs(existing_only=True) — the ordered fallback list above
  • merge_common_tool_path(existing_path=None, prepend=False) — merges the fallbacks into a PATH string without touching explicitly configured PATH entries
  • ensure_common_tool_paths(prepend=False) — same, but updates os.environ['PATH'] in place

Then:

  • hermes_cli/doctor.py calls ensure_common_tool_paths() right before the External Tools check
  • tools/browser_tool.py derives _SANE_PATH / _SANE_PATH_DIRS from common_tool_path_dirs(existing_only=False)

This makes the two callers agree on the same fallback set and removes the need for users to ship an external wrapper script just to get a green doctor.

Environment

  • macOS (Apple Silicon), zsh
  • Node managed via mise
  • Hermes launched both from an interactive shell (works) and from a LaunchAgent / non-interactive launcher (fails before this change)

I have a working patch with tests and will open a PR.

extent analysis

TL;DR

To fix the issue, centralize the fallback list in a helper module and update the PATH environment variable to include user-level shims and platform locations.

Guidance

  • Identify the PATH environment variable differences between interactive and non-interactive shell launches to understand why hermes doctor can't find Node.js.
  • Create a centralized helper module (e.g., hermes_cli/path_env.py) to manage the fallback list of tool directories, including user-level shims and platform locations.
  • Update hermes_cli/doctor.py to call the helper module's function to ensure the PATH environment variable includes the fallback directories before checking external tools.
  • Consider deriving the _SANE_PATH and _SANE_PATH_DIRS in tools/browser_tool.py from the centralized helper module for consistency.

Example

# hermes_cli/path_env.py
import os

def common_tool_path_dirs(existing_only=True):
    # ordered fallback list of tool directories
    dirs = [
        '~/.local/bin',
        '~/.local/share/mise/shims',
        '~/.asdf/shims',
        '~/.nvm/versions/node/*/bin',
        '/opt/homebrew/bin',
        '/usr/local/bin',
        '/usr/bin',
        '/bin'
    ]
    # ...

Notes

This solution assumes that the issue is caused by the difference in PATH environment variables between interactive and non-interactive shell launches. The proposed fix centralizes the fallback list and updates the PATH environment variable to ensure consistency.

Recommendation

Apply the proposed fix by centralizing the fallback list in a helper module and updating the PATH environment variable, as this approach ensures consistency between hermes doctor and tools/browser_tool.py and removes the need for external wrapper scripts.

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…

FAQ

Expected behavior

hermes doctor and tools/browser_tool should both fall back to a common, well-known set of tool directories that includes:

  • User-level shims: ~/.local/bin, ~/.local/share/mise/shims, ~/.asdf/shims, ~/.nvm/versions/node/*/bin, ~/.bun/bin
  • Platform locations: /opt/homebrew/{bin,sbin}, Termux dirs, /usr/local/{bin,sbin}, /usr/{bin,sbin}, /{bin,sbin}

…so non-interactive launches behave consistently with what the user sees in an interactive shell.

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 hermes doctor / browser tool can't find Node when launched non-interactively (mise/asdf/nvm shims, Homebrew) [1 pull requests, 1 participants]