Bug Description
resolve_skill_config_values() in agent/skill_utils.py expands ~ in skill config default values using os.path.expanduser(), which resolves against the Python process's own HOME (/opt/data in containerized setups). However, Hermes independently sets a
different HOME ({HERMES_HOME}/home/) for terminal/background subprocesses via get_subprocess_home().
Steps to Reproduce
- Start Hermes in a Docker environment with HERMES_HOME=/opt/data
- Verify that the entrypoint has created {HERMES_HOME}/home/:
ls -d /opt/data/home
- Confirm the Python process HOME differs from the subprocess HOME:
import os
from hermes_constants import get_subprocess_home
print(f"Python process HOME: {os.environ.get('HOME')}") # e.g. /opt/data
print(f"Subprocess HOME: {get_subprocess_home()}") # e.g. /opt/data/home
4. Trigger skill config resolution (e.g. via prompt injection with an enabled llm-wiki skill that declares default: "~/wiki"):
[Skill config ... wiki.path = /opt/data/wiki]
5. Observe that the injected path uses the Python process HOME (/opt/data/wiki) instead of the subprocess HOME (/opt/data/home/wiki)
6. Any file-creating tool (e.g. wiki init) will write to /opt/data/wiki/ on disk, but subprocesses will look for their configs at /opt/data/home/wiki/
Expected Behavior
wiki.path = /opt/data/home/wiki
Actual Behavior
wiki.path = /opt/data/wiki
Affected Component
Skills (skill loading, skill hub, skill guard)
Messaging Platform (if gateway-related)
No response
Debug Report
Report https://paste.rs/oO3UO
agent.log https://paste.rs/AO4i6
gateway.log https://paste.rs/ZEJeP
Operating System
macOS 26.4.1
Python Version
3.13.5
Hermes Version
v0.10.0 (2026.4.16)
Additional Logs / Traceback (optional)
Root Cause Analysis (optional)
agent/skill_utils.py:406-408:
if isinstance(value, str) and ("~" in value or "${" in value):
value = os.path.expanduser(os.path.expandvars(value))
os.path.expanduser() uses the Python process's HOME env var, which is never modified by Hermes. Meanwhile, hermes_constants.get_subprocess_home() (which returns {HERMES_HOME}/home/ when that directory exists) governs the actual HOME seen by tools
spawned in terminals or background processes.
Evidence
- entrypoint.sh creates {HERMES_HOME}/home/ explicitly for subprocess use: "home/ subdirectory is a per-profile HOME for subprocesses"
- tools/environments/local.py injects get_subprocess_home() as HOME into subprocess environments
- hermes_constants.get_subprocess_home() docstring explicitly states: "The Python process's own os.environ["HOME"] and Path.home() are never modified — only subprocess environments should inject this value."
Yet resolve_skill_config_values() silently uses the Python process HOME instead.
Impact
Any skill declaring a ~/... default path in metadata.hermes.config is affected, including:
- llm-wiki (default: ~/wiki)
- Any other skill using ~/cache, ~/notes, ~/workspace, etc.
The skill config injection block in prompts shows an incorrect path that doesn't match the actual runtime environment.
Proposed Fix (optional)
In resolve_skill_config_values(), prefer get_subprocess_home() over raw os.path.expanduser() when expanding ~/ paths:
from hermes_constants import get_config_path, get_skills_dir, get_subprocess_home
subprocess_home = get_subprocess_home()
if isinstance(value, str) and ("~" in value or "${" in value):
expanded = os.path.expandvars(value)
if subprocess_home and expanded.startswith("~/"):
value = os.path.join(subprocess_home, expanded[2:])
elif subprocess_home and expanded == "~":
value = subprocess_home
else:
value = os.path.expanduser(expanded)
This ensures ~/wiki injected as /opt/data/home/wiki (matching subprocess HOME) instead of /opt/data/wiki (matching Python process HOME).
Are you willing to submit a PR for this?
Bug Description
resolve_skill_config_values() in agent/skill_utils.py expands ~ in skill config default values using os.path.expanduser(), which resolves against the Python process's own HOME (/opt/data in containerized setups). However, Hermes independently sets a
different HOME ({HERMES_HOME}/home/) for terminal/background subprocesses via get_subprocess_home().
Steps to Reproduce
ls -d /opt/data/home
import os
from hermes_constants import get_subprocess_home
print(f"Python process HOME: {os.environ.get('HOME')}") # e.g. /opt/data
print(f"Subprocess HOME: {get_subprocess_home()}") # e.g. /opt/data/home
4. Trigger skill config resolution (e.g. via prompt injection with an enabled llm-wiki skill that declares default: "~/wiki"):
[Skill config ... wiki.path = /opt/data/wiki]
5. Observe that the injected path uses the Python process HOME (/opt/data/wiki) instead of the subprocess HOME (/opt/data/home/wiki)
6. Any file-creating tool (e.g. wiki init) will write to /opt/data/wiki/ on disk, but subprocesses will look for their configs at /opt/data/home/wiki/
Expected Behavior
wiki.path = /opt/data/home/wiki
Actual Behavior
wiki.path = /opt/data/wiki
Affected Component
Skills (skill loading, skill hub, skill guard)
Messaging Platform (if gateway-related)
No response
Debug Report
Operating System
macOS 26.4.1
Python Version
3.13.5
Hermes Version
v0.10.0 (2026.4.16)
Additional Logs / Traceback (optional)
Root Cause Analysis (optional)
agent/skill_utils.py:406-408:
os.path.expanduser() uses the Python process's HOME env var, which is never modified by Hermes. Meanwhile, hermes_constants.get_subprocess_home() (which returns {HERMES_HOME}/home/ when that directory exists) governs the actual HOME seen by tools
spawned in terminals or background processes.
Evidence
Yet resolve_skill_config_values() silently uses the Python process HOME instead.
Impact
Any skill declaring a ~/... default path in metadata.hermes.config is affected, including:
The skill config injection block in prompts shows an incorrect path that doesn't match the actual runtime environment.
Proposed Fix (optional)
In resolve_skill_config_values(), prefer get_subprocess_home() over raw os.path.expanduser() when expanding ~/ paths:
This ensures ~/wiki injected as /opt/data/home/wiki (matching subprocess HOME) instead of /opt/data/wiki (matching Python process HOME).
Are you willing to submit a PR for this?