NousResearch/hermes-agent · error · ValueError
path is a sensitive credential file and cannot be attached
Error message
path is a sensitive credential file and cannot be attached
What it means
The attached file reference matches a sensitive credential file exactly (e.g. ~/.hermes/.env or a file in _SENSITIVE_HOME_FILES), so reference expansion refuses to inline its contents. This is the first, exact-match tier of _ensure_reference_path_allowed in agent/context_references.py, which protects credential material from being pulled into conversation context.
Source
Thrown at agent/context_references.py:495
try:
resolved.relative_to(allowed_root)
except ValueError as exc:
raise ValueError("path is outside the allowed workspace") from exc
return resolved
def _ensure_reference_path_allowed(path: Path) -> None:
from hermes_constants import get_hermes_home
home = Path(os.path.expanduser("~")).resolve()
hermes_home = get_hermes_home().resolve()
blocked_exact = {home / rel for rel in _SENSITIVE_HOME_FILES}
blocked_exact.add(hermes_home / ".env")
blocked_dirs = [home / rel for rel in _SENSITIVE_HOME_DIRS]
blocked_dirs.extend(hermes_home / rel for rel in _SENSITIVE_HERMES_DIRS)
if path in blocked_exact:
raise ValueError("path is a sensitive credential file and cannot be attached")
for blocked_dir in blocked_dirs:
try:
path.relative_to(blocked_dir)
except ValueError:
continue
raise ValueError("path is a sensitive credential or internal Hermes path and cannot be attached")
# Anchor to the canonical read deny-list (agent/file_safety.get_read_block_error),
# the single source of truth used by the file/terminal read path. The narrow
# list above predates that guard and never caught the real credential stores:
# provider keys (auth.json), Anthropic OAuth tokens (.anthropic_oauth.json),
# MCP OAuth material (mcp-tokens/), webhook HMAC secrets, and project-local
# .env files. That gap matters because the gateway feeds UNTRUSTED remote
# message text into reference expansion, so `@file:~/.hermes/auth.json` from a
# chat peer would otherwise read the operator's keys straight into context.
# Routing through the canonical guard closes the gap today and keeps this path
# protected automatically whenever that deny-list grows.View on GitHub (pinned to c896c09c42)
Solutions
- Do not attach credential files; paste only the non-secret key NAMES you need help with.
- Create a sanitized copy (secrets redacted) inside the workspace and attach that instead.
- Reference documentation or an .env.example file rather than the live .env.
Example fix
# before @file:~/.hermes/.env # after — sanitized template inside the workspace @file:./env.example
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
CREDENTIAL_NAMES = {'.env', '.env.local'} # extend to match your policy
def is_credential_file(p: Path) -> bool:
return p.name in CREDENTIAL_NAMES or p.suffix in {'.pem', '.key'} Try / catch
try:
attach(path)
except ValueError as e:
if "sensitive credential file" in str(e):
# never retry with the same path; offer a redacted copy instead
... Prevention
- Never attach live .env / key files; use redacted copies
- Reference .env.example templates instead of real secrets
- Treat all credential-path blocks as final — do not attempt bypasses
When it happens
Trigger: A message with @file:~/.hermes/.env or @file: pointing at any of the exact sensitive home files (e.g. ~/.ssh/authorized_keys-style entries in _SENSITIVE_HOME_FILES). The resolved Path is compared by equality against blocked_exact.
Common situations: Trying to show the agent your configuration for debugging ('read my .env so you can fix the API key'); a remote gateway peer probing for credential files via @file: references.
Related errors
- path is outside the allowed workspace
- path is a sensitive credential or internal Hermes path and c
- path could not be verified against the credential deny-list
- ${label} exited and ${dashboardIndexUrl(baseUrl)} is served
- Could not repair the desktop installation ID.
AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14).
Data as JSON: /api/errors/7a67c3a4a0105cc9.
Report an issue: GitHub.