Skip to content

[Bug]: /reload doesn't invalidate cached SSH environments after SSH config changes #71085

Description

@ajzrva-sys

Bug Description

When SSH connection settings (host, port, user, key) are updated in .env and the user runs /reload, the cached SSHEnvironment objects in _active_environments retain the old connection parameters. Subsequent terminal tool calls reuse the stale environment instead of creating a new one with the updated config.

Steps to Reproduce

  1. Configure SSH terminal backend:
TERMINAL_ENV=ssh
TERMINAL_SSH_HOST=example.com
TERMINAL_SSH_PORT=2222
TERMINAL_SSH_USER=root
TERMINAL_SSH_KEY=~/.ssh/id_ed25519
  1. Start a Hermes session — terminal commands work via SSH on port 2222.

  2. Remote host restarts and gets a new SSH port (3333). Update .env:

TERMINAL_SSH_PORT=3333
  1. Run /reload in the session. Output shows env vars updated.

  2. Execute a terminal command — fails because the cached SSHEnvironment still uses port 2222.

Expected Behavior

/reload should detect SSH config changes and invalidate cached SSH environments, so the next terminal call creates a fresh connection with the updated config.

Actual Behavior

/reload updates os.environ via reload_env() but does not touch _active_environments in terminal_tool.py. The cached SSHEnvironment at _active_environments[task_id] still holds self.port = 2222 (old value). The environment lookup at terminal_tool.py:2246-2252 reuses it:

_existing_key = (
    effective_task_id if effective_task_id in _active_environments
    else (task_id if task_id and task_id in _active_environments else None)
)
if _existing_key is not None:
    _last_activity[_existing_key] = time.time()
    env = _active_environments[_existing_key]
    needs_creation = False

The stale env persists until the lifetime_seconds idle timeout (default 300s) expires, but if the session is active, it never does.

Error Logs

# .env has correct port:
TERMINAL_SSH_PORT=3333

# But errors show stale port:
RuntimeError: SSH connection failed: ssh: connect to host example.com port 2222: Operation timed out

Manual SSH with the correct port works fine.

Environment

  • macOS (arm64)
  • Hermes Agent (latest main)
  • SSH backend with cloud pod (dynamic port assignment)

Proposed Fix

In the /reload handler in cli.py, after reload_env(), detect SSH config changes and call cleanup_all_environments() to force recreation:

elif canonical == "reload":
    from hermes_cli.config import reload_env
    _ssh_keys = {"TERMINAL_SSH_HOST", "TERMINAL_SSH_PORT",
                 "TERMINAL_SSH_USER", "TERMINAL_SSH_KEY"}
    _before = {k: os.environ.get(k) for k in _ssh_keys}
    count = reload_env()
    print(f"  Reloaded .env ({count} var(s) updated)")
    _after = {k: os.environ.get(k) for k in _ssh_keys}
    if _before != _after:
        try:
            from tools.terminal_tool import cleanup_all_environments
            cleaned = cleanup_all_environments()
            if cleaned:
                print(f"  Cleared {cleaned} cached environment(s) (SSH config changed)")
        except Exception as e:
            logger.debug("Failed to clean environments after reload: %s", e)

Are you willing to submit a PR for this?

  • I'd like to fix this myself and submit a PR

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium — degraded but workaround existsarea/configConfig system, migrations, profilesbackend/sshSSH remote executionsweeper:risk-compatibilitySweeper risk: may break existing users, config, migrations, defaults, or upgradestool/terminalTerminal execution and process managementtype/bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions