hermes - ✅(Solved) Fix Bug: read_file tilde expansion broken in sandboxed profiles (HOME points to profile sandbox) [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#28456Fetched 2026-05-20 04:03:40
View on GitHub
Comments
0
Participants
1
Timeline
7
Reactions
0
Author
Participants
Timeline (top)
labeled ×5cross-referenced ×2

read_file (and any tool using Path.expanduser()) resolves ~ to the profile sandbox home instead of the real user home when a profile has a home/ directory.

Error Message

Any sandboxed profile reading shared data via ~/ paths silently loses access. No exception raised — just file not found.

Root Cause

Path.expanduser() resolves ~ via os.environ["HOME"]. The gateway process itself has HOME set to the profile sandbox home — violating the documented behavior of get_subprocess_home() which states the Python process HOME is never modified.

Fix Action

Fix / Workaround

  1. Preferred: File tools resolve ~ via pwd.getpwuid(os.getuid()).pw_dir instead of Path.expanduser() (ignores HOME env).
  2. Alternative: Gateway startup must not set process-level HOME to the profile sandbox — only inject into subprocess envs as documented.
  3. Workaround: Use absolute paths in skills.

PR fix notes

PR #28469: fix: resolve ~ to real user home in sandboxed profiles

Description (problem / solution / changelog)

Problem

In sandboxed profiles where local.py or code_execution_tool.py sets child_env["HOME"]=profile_home, Path.expanduser() and os.path.expanduser() resolve ~ to the profile home directory instead of the real user home. This caused read_file("~/.hermes/...") to fail with FileNotFoundError in sandboxed profiles.

From the issue reporter (/@paulbram):

read_file("~/.hermes/shared/echo-data/context-snapshot.md")
# Resolves to: /home/paulbram/.hermes/profiles/threepio/home/.hermes/shared/...
# Expected:    /home/paulbram/.hermes/shared/...
# Result: FileNotFoundError (silent)

get_subprocess_home() documents that the Python process own os.environ["HOME"] and Path.home() are never modified. However, the behavior described in the issue suggests HOME is being overridden in the main process too (possibly via shell environment before gateway startup).

Solution

Add _expanduser_safe() which replaces any leading ~ with Path.home() before calling expanduser(). Path.home() consults the password database (pwd.getpwuid) and is immune to HOME env var overrides, so it always returns the real user home.

3 call sites updated in tools/file_tools.py:

  • _resolve_path_for_task() — primary path resolution for all file tools
  • _is_blocked_device() — device-path security check
  • _check_sensitive_path() — sensitive-path security check

Changes

FileChange
tools/file_tools.py+22: _expanduser_safe() helper; 3 call sites updated
tests/tools/test_file_tools.py+44: 4 new TestExpanduserSafe test cases

Testing

33 passed in tests/tools/test_file_tools.py (including 4 new tests)

Fixes #28456

Changed files

  • tests/tools/test_file_tools.py (modified, +44/-0)
  • tools/file_tools.py (modified, +22/-3)

Code Example

read_file("~/.hermes/shared/echo-data/context-snapshot.md")
# Resolves to: /home/paulbram/.hermes/profiles/threepio/home/.hermes/shared/echo-data/context-snapshot.md
# Expected:    /home/paulbram/.hermes/shared/echo-data/context-snapshot.md
# Result: FileNotFoundError (silent)
RAW_BUFFERClick to expand / collapse

Summary

read_file (and any tool using Path.expanduser()) resolves ~ to the profile sandbox home instead of the real user home when a profile has a home/ directory.

Profile

Any named profile with a home/ subdirectory (e.g. profiles/threepio/home/ exists).

Symptom

read_file("~/.hermes/shared/echo-data/context-snapshot.md")
# Resolves to: /home/paulbram/.hermes/profiles/threepio/home/.hermes/shared/echo-data/context-snapshot.md
# Expected:    /home/paulbram/.hermes/shared/echo-data/context-snapshot.md
# Result: FileNotFoundError (silent)

Root Cause

Path.expanduser() resolves ~ via os.environ["HOME"]. The gateway process itself has HOME set to the profile sandbox home — violating the documented behavior of get_subprocess_home() which states the Python process HOME is never modified.

Introduced By

Commit 4fb42d019"fix: per-profile subprocess HOME isolation (#4426) (#7357)" (April 10 2026). Activates when {HERMES_HOME}/home/ directory exists.

Impact

Any sandboxed profile reading shared data via ~/ paths silently loses access. No exception raised — just file not found.

Fix Options

  1. Preferred: File tools resolve ~ via pwd.getpwuid(os.getuid()).pw_dir instead of Path.expanduser() (ignores HOME env).
  2. Alternative: Gateway startup must not set process-level HOME to the profile sandbox — only inject into subprocess envs as documented.
  3. Workaround: Use absolute paths in skills.

Repro Steps

  1. mkdir ~/.hermes/profiles/myprofile/home/
  2. Run Hermes under that profile
  3. Call read_file("~/.hermes/any-shared-file.txt") where file exists at real home but not sandbox
  4. Observe: file not found

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 Bug: read_file tilde expansion broken in sandboxed profiles (HOME points to profile sandbox) [1 pull requests, 1 participants]