Bug Description
When TERMINAL_DOCKER_VOLUMES is set to a non-JSON value (e.g. the literal string None), all subprocess tools (terminal, execute_code) fail immediately with a fatal ValueError — even when terminal.backend: local and Docker volumes are completely irrelevant to the setup.
The agent becomes completely unusable with no way to recover except fixing the env var externally.
Steps to Reproduce
- Set an invalid JSON value for
TERMINAL_DOCKER_VOLUMES:
export TERMINAL_DOCKER_VOLUMES=None
- Ensure
terminal.backend: local in config.yaml
- Start any session that uses
terminal or execute_code tools
- Observe crash:
ValueError: Invalid value for TERMINAL_DOCKER_VOLUMES: 'None' (expected valid JSON).
Check ~/.hermes/.env or environment variables.
Expected Behavior
Invalid TERMINAL_DOCKER_VOLUMES should not crash non-Docker backends. If terminal.backend is local, Docker-specific env vars should either not be parsed at all, or parse failures should be caught gracefully with a warning and a fallback to the default value ([]).
Actual Behavior
All subprocess tools crash on init. Every terminal() or execute_code() call raises ValueError, making the agent completely inoperable until the env var is manually corrected. The error message points the user to .env, but the real cause may be in config.yaml or the gateway's env bridge.
Affected Component
- Tools (terminal, file ops, web, code execution, etc.)
Messaging Platform
Debug Report
Report https://paste.rs/OLP88
agent.log https://dpaste.com/42ELVLJY3
gateway.log https://dpaste.com/3XX4CUW7V
Operating System
Debbian GNU/Linux 13 (trixie), running inside Docker container (OrbStack, --network host)
Python Version
3.13.5
Hermes Version
Hermes Agent v0.16.0 (2026.6.5)
Additional Logs / Traceback (optional)
The exact error (reproduced on v0.16.0):
ValueError: Invalid value for TERMINAL_DOCKER_VOLUMES: 'None' (expected valid JSON).
Check ~/.hermes/.env or environment variables.
Root Cause Analysis (optional)
Two separate issues compound:
1. Eager unconditional parsing in terminal_tool.py
_get_env_config() calls _parse_env_var() with json.loads for Docker-specific env vars at module initialization time, before checking what terminal.backend is:
"docker_volumes": _parse_env_var("TERMINAL_DOCKER_VOLUMES", "[]", json.loads, "valid JSON"),
"docker_env": _parse_env_var("TERMINAL_DOCKER_ENV", "{}", json.loads, "valid JSON"),
"docker_extra_args": _parse_env_var("TERMINAL_DOCKER_EXTRA_ARGS", "[]", json.loads, "valid JSON"),
These run regardless of whether the backend is local, docker, ssh, or anything else.
2. Unconditional env var bridge in gateway/run.py
The *terminal_env_map bridge unconditionally exports all terminal.docker_* config keys as environment variables when the gateway starts, regardless of backend:
*terminal_env_map = {
...
"docker_volumes": "TERMINAL_DOCKER_VOLUMES",
"docker_env": "TERMINAL_DOCKER_ENV",
"docker_image": "TERMINAL_DOCKER_IMAGE",
...
}
If docker_volumes is misconfigured in config.yaml (e.g. set to None/null in YAML), str(None) produces the literal string "None", which then crashes json.loads().
Proposed Fix (optional)
Make Docker-specific env var parsing lazy — only evaluate docker_volumes, docker_env, docker_extra_args etc. when the active backend is a container backend (docker, singularity, modal, daytona). For local and ssh backends, these values should be ignored entirely and never parsed.
Bug Description
When
TERMINAL_DOCKER_VOLUMESis set to a non-JSON value (e.g. the literal stringNone), all subprocess tools (terminal,execute_code) fail immediately with a fatalValueError— even whenterminal.backend: localand Docker volumes are completely irrelevant to the setup.The agent becomes completely unusable with no way to recover except fixing the env var externally.
Steps to Reproduce
TERMINAL_DOCKER_VOLUMES:export TERMINAL_DOCKER_VOLUMES=Noneterminal.backend: localin config.yamlterminalorexecute_codetoolsExpected Behavior
Invalid
TERMINAL_DOCKER_VOLUMESshould not crash non-Docker backends. Ifterminal.backendislocal, Docker-specific env vars should either not be parsed at all, or parse failures should be caught gracefully with a warning and a fallback to the default value ([]).Actual Behavior
All subprocess tools crash on init. Every
terminal()orexecute_code()call raisesValueError, making the agent completely inoperable until the env var is manually corrected. The error message points the user to.env, but the real cause may be in config.yaml or the gateway's env bridge.Affected Component
Messaging Platform
Debug Report
Report https://paste.rs/OLP88
agent.log https://dpaste.com/42ELVLJY3
gateway.log https://dpaste.com/3XX4CUW7V
Operating System
Debbian GNU/Linux 13 (trixie), running inside Docker container (OrbStack,
--network host)Python Version
3.13.5
Hermes Version
Hermes Agent v0.16.0 (2026.6.5)
Additional Logs / Traceback (optional)
The exact error (reproduced on v0.16.0):
Root Cause Analysis (optional)
Two separate issues compound:
1. Eager unconditional parsing in
terminal_tool.py_get_env_config()calls_parse_env_var()withjson.loadsfor Docker-specific env vars at module initialization time, before checking whatterminal.backendis:These run regardless of whether the backend is
local,docker,ssh, or anything else.2. Unconditional env var bridge in
gateway/run.pyThe
*terminal_env_mapbridge unconditionally exports allterminal.docker_*config keys as environment variables when the gateway starts, regardless of backend:If
docker_volumesis misconfigured in config.yaml (e.g. set toNone/nullin YAML),str(None)produces the literal string"None", which then crashesjson.loads().Proposed Fix (optional)
Make Docker-specific env var parsing lazy — only evaluate
docker_volumes,docker_env,docker_extra_argsetc. when the active backend is a container backend (docker,singularity,modal,daytona). Forlocalandsshbackends, these values should be ignored entirely and never parsed.