hermes - 💡(How to fix) Fix Windows: HERMES_HOME fallback to ~/.hermes creates phantom duplicate directory

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…

The Windows installer (install.ps1) correctly sets $env:LOCALAPPDATA\hermes as HERMES_HOME and persists it as a Windows User environment variable. However, two interrelated issues cause a phantom ~/.hermes/ directory to be silently recreated even after deletion:

Issue 1: get_hermes_home() / get_default_hermes_root() are not Windows-aware

# hermes_constants.py:101
return Path.home() / ".hermes"

The fallback is hardcoded to ~/.hermes regardless of platform. The code comment in auth.py:4007 explicitly documents:

%LOCALAPPDATA%\hermes on native Windows

But get_default_hermes_root() always returns Path.home() / ".hermes" — the implementation does not match the documented intent. On Windows, the default Hermes home should be %LOCALAPPDATA%\hermes (consistent with the installer and Windows conventions).

Issue 2: Hardcoded ~/.hermes paths bypass get_hermes_home()

Multiple files bypass the canonical get_hermes_home() resolver and hardcode Path.home() / ".hermes" directly. PR #19947 identifies 11 production files with this pattern. When a subprocess or code path hits these call sites without HERMES_HOME in its environment, it silently initializes a fresh home at ~/.hermes/ — creating a dead shell directory with no config.yaml, no .env, empty skills/, and a 4KB memory_store.db.

The result: even after deleting ~/.hermes/, it reappears the next time a gateway background task, cron job, or any subprocess runs without HERMES_HOME inherited.

Evidence from logs inside ~/.hermes/logs/:

2026-05-21 22:18:28,444 INFO hermes_cli.plugins: Plugin discovery complete: 26 found, 22 enabled
2026-05-21 22:18:30,642 WARNING agent.auxiliary_client: Auxiliary: marking openrouter unhealthy...

These are real Hermes startup logs from a process using ~/.hermes/ as its home — same Hermes installation at %LOCALAPPDATA%/hermes/hermes-agent/venv/, but without HERMES_HOME set, it fell back to ~/.hermes/ and logged into a ghost directory.

Root Cause

  • Confusing dual-directory state (%LOCALAPPDATA%\hermes + ~/.hermes/)
  • ~/.hermes/ is a dead shell — no config, no skills, no useful data — but Hermes processes run inside it (wasting resources)
  • The directory keeps reappearing after deletion because subprocess spawners don't guarantee HERMES_HOME propagation

Fix Action

Fix / Workaround

  1. Audit subprocess spawners (gateway, cron scheduler, kanban dispatcher, web server actions) to ensure HERMES_HOME is always propagated into the child environment.

Code Example

# hermes_constants.py:101
return Path.home() / ".hermes"

---

2026-05-21 22:18:28,444 INFO hermes_cli.plugins: Plugin discovery complete: 26 found, 22 enabled
2026-05-21 22:18:30,642 WARNING agent.auxiliary_client: Auxiliary: marking openrouter unhealthy...
RAW_BUFFERClick to expand / collapse

Bug: Windows HERMES_HOME fallback creates phantom ~/.hermes/ when subprocesses don't inherit the env var

Environment

  • OS: Windows 11 (native, not WSL)
  • Hermes: 0.14.0 (installed via install.ps1)
  • Shell: Git Bash / MSYS2

Description

The Windows installer (install.ps1) correctly sets $env:LOCALAPPDATA\hermes as HERMES_HOME and persists it as a Windows User environment variable. However, two interrelated issues cause a phantom ~/.hermes/ directory to be silently recreated even after deletion:

Issue 1: get_hermes_home() / get_default_hermes_root() are not Windows-aware

# hermes_constants.py:101
return Path.home() / ".hermes"

The fallback is hardcoded to ~/.hermes regardless of platform. The code comment in auth.py:4007 explicitly documents:

%LOCALAPPDATA%\hermes on native Windows

But get_default_hermes_root() always returns Path.home() / ".hermes" — the implementation does not match the documented intent. On Windows, the default Hermes home should be %LOCALAPPDATA%\hermes (consistent with the installer and Windows conventions).

Issue 2: Hardcoded ~/.hermes paths bypass get_hermes_home()

Multiple files bypass the canonical get_hermes_home() resolver and hardcode Path.home() / ".hermes" directly. PR #19947 identifies 11 production files with this pattern. When a subprocess or code path hits these call sites without HERMES_HOME in its environment, it silently initializes a fresh home at ~/.hermes/ — creating a dead shell directory with no config.yaml, no .env, empty skills/, and a 4KB memory_store.db.

The result: even after deleting ~/.hermes/, it reappears the next time a gateway background task, cron job, or any subprocess runs without HERMES_HOME inherited.

Evidence from logs inside ~/.hermes/logs/:

2026-05-21 22:18:28,444 INFO hermes_cli.plugins: Plugin discovery complete: 26 found, 22 enabled
2026-05-21 22:18:30,642 WARNING agent.auxiliary_client: Auxiliary: marking openrouter unhealthy...

These are real Hermes startup logs from a process using ~/.hermes/ as its home — same Hermes installation at %LOCALAPPDATA%/hermes/hermes-agent/venv/, but without HERMES_HOME set, it fell back to ~/.hermes/ and logged into a ghost directory.

Impact

  • Confusing dual-directory state (%LOCALAPPDATA%\hermes + ~/.hermes/)
  • ~/.hermes/ is a dead shell — no config, no skills, no useful data — but Hermes processes run inside it (wasting resources)
  • The directory keeps reappearing after deletion because subprocess spawners don't guarantee HERMES_HOME propagation

Proposed Fix

  1. Make get_default_hermes_root() platform-aware — on Windows (sys.platform == "win32"), return Path(os.environ.get("LOCALAPPDATA", Path.home() / "AppData" / "Local")) / "hermes" instead of Path.home() / ".hermes".

  2. Make get_hermes_home()'s fallback also platform-aware — same logic, since the two functions diverge in behavior on Windows.

  3. Merge PR #19947 — route all 11 hardcoded Path.home() / ".hermes" call sites through get_hermes_home().

  4. Audit subprocess spawners (gateway, cron scheduler, kanban dispatcher, web server actions) to ensure HERMES_HOME is always propagated into the child environment.

Related

  • PR #19947: fix(config): route HERMES_HOME callsites through get_hermes_home()
  • Issue #2512, #10359: Native Windows Support
  • Issue #18594: HERMES_HOME profile fallback warning

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 - 💡(How to fix) Fix Windows: HERMES_HOME fallback to ~/.hermes creates phantom duplicate directory