Summary
Multiple subprocess.run() and network API calls throughout the codebase lack a timeout parameter. If any of these external processes or services hang, Hermes blocks indefinitely with no recovery path.
Affected locations
hermes_cli/main.py — cmd_update()
Lines 137, 140, 150, 165, 171, 179, 181, 188: subprocess.run() calls for git fetch, git pull, pip install, npm install — none have timeout.
hermes_cli/doctor.py
- Line 260:
subprocess.run(["docker", "info"]) — no timeout
- Lines 280-284: SSH check uses
-o ConnectTimeout=5 as an SSH arg, but the subprocess.run() itself has no timeout — a connected-but-hung SSH session blocks forever
hermes_cli/gateway.py
All 18 subprocess.run() calls (lines 159, 160, 174, 175, 182, 186, 190, 194, 206, 212, 229, 294, 305, 314, 318, 326, 343) plus find_gateway_pids() at line 32 — none have timeout.
tools/web_tools.py — Firecrawl API
Lines 549-551, 684-687, 958-961: .search(), .scrape(), .crawl() calls pass no explicit timeout. The SDK may have internal defaults, but they're not guaranteed.
Suggested fix
Add timeout=30 (or appropriate values) to all subprocess.run() calls. For network APIs, either pass timeout to the SDK or wrap in a signal.alarm / asyncio.wait_for. For long-running operations like pip install or npm install, use a longer timeout (e.g., 120s) but not infinite.
Impact
- Severity: High — a single hung subprocess can freeze the entire CLI or gateway indefinitely
- Risk: None — adding timeouts doesn't change behavior for calls that complete normally
- Effort: Small — mechanical change across ~25 call sites
Ref
UX audit item #1.
Summary
Multiple
subprocess.run()and network API calls throughout the codebase lack atimeoutparameter. If any of these external processes or services hang, Hermes blocks indefinitely with no recovery path.Affected locations
hermes_cli/main.py—cmd_update()Lines 137, 140, 150, 165, 171, 179, 181, 188:
subprocess.run()calls forgit fetch,git pull,pip install,npm install— none havetimeout.hermes_cli/doctor.pysubprocess.run(["docker", "info"])— no timeout-o ConnectTimeout=5as an SSH arg, but thesubprocess.run()itself has no timeout — a connected-but-hung SSH session blocks foreverhermes_cli/gateway.pyAll 18
subprocess.run()calls (lines 159, 160, 174, 175, 182, 186, 190, 194, 206, 212, 229, 294, 305, 314, 318, 326, 343) plusfind_gateway_pids()at line 32 — none have timeout.tools/web_tools.py— Firecrawl APILines 549-551, 684-687, 958-961:
.search(),.scrape(),.crawl()calls pass no explicit timeout. The SDK may have internal defaults, but they're not guaranteed.Suggested fix
Add
timeout=30(or appropriate values) to allsubprocess.run()calls. For network APIs, either passtimeoutto the SDK or wrap in asignal.alarm/asyncio.wait_for. For long-running operations likepip installornpm install, use a longer timeout (e.g., 120s) but not infinite.Impact
Ref
UX audit item #1.