Hermes Self-Repair
Diagnose and fix a broken or stuck Hermes installation itself — failed/partial
updates, desktop app rebuilds, gateway not restarting, and provider config
rejections (HTTP 400 on model params). This is about repairing the tool; for
normal usage/configuration questions use the bundled hermes-agent skill.
When to Use
hermes updatefails partway, hangs, or leaves the version stale.- Desktop app (Electron) fails to rebuild after an update (
EBADENGINE,✗ Desktop dependency install failed, or stamp says build needed but exe is old). - Gateway doesn't come back after an update; sessions error on provider params.
- User reports "update keeps failing" from the desktop app's update button.
- User reports a desktop UI feature "missing" after an update — check hidden-by-state chrome before assuming a regression.
Diagnosis First
Logs tell you which stage failed — read them before retrying anything:
# $LOCALAPPDATA/hermes/logs/ on Windows (Linux/macOS: ~/.hermes/logs/)
update.log # per-stage update results; grep for "✗", "error", "fail"
desktop.log # desktop updater: "[updates] venv-blocked", "Update aborted"
errors.log # agent/runtime errors with tracebacks
gui.log # desktop backend boot
Quick health snapshot:
hermes --version # current version + "update available" line
hermes version # "Up to date" confirmation
hermes gateway status # gateway process detected?
Windows Update Pitfalls
- npm EBADENGINE on desktop build: the repo's
package.jsonengines block a gap range, e.g."npm": "<11.10.0 || >=11.17.0"— npm versions inside the gap (11.10–11.16) fail with "Not compatible with your version of node/npm". Fix:npm install -g npm@12(or any version in an accepted range), then retry. Verify the accepted range from the repopackage.jsonbefore choosing a version. - venv-blocked:
desktop.logshows[updates] venv-blocked: N process(es) hold the install/Update aborted: another Hermes process is using this installation. Any running Hermes process locks the venv on Windows. Run updates from a plain terminal with the desktop app closed, or usehermes update --force. - venv-blocked that survives gateway restarts (long-path truncation bug):
if the reported holder is a
python.exewhose path shows a truncated cmdline (e.g. ends mid-token at...cpython-3.1) and is the managed-runtime half of a gateway (.hermes-runtime\python\generation-*\...\python.exe -m hermes_cli.main gateway run), the pausable-gateway exemption fails because_detect_venv_python_processes()inhermes_cli/update_cmd.pytruncates cmdlines to 120 chars (cmdline_raw[:120]) — thegateway runtokens land past the cut, so the preflight scan reports it as a hard blocker and the Desktop update aborts every time while the (auto-started, e.g. Startup folder.vbs) gateway runs. Fix: return the fullcmdline_rawfrom the detector (truncate only in_format_venv_python_holders_messagedisplay). Regression test:tests/hermes_cli/test_update_venv_health.py::test_detect_venv_python_keeps_full_cmdline_for_gateway_classification. The updater's autostash (_stash_local_changes_if_needed/_restore_stashed_changes) carries local patches acrosshermes update. - Update killed mid-way by your own timeout: a partial update leaves core
upgraded (e.g. 0.19.1 → 0.20.0 done) but later stages (desktop rebuild,
gateway restart) unfinished. Re-run
hermes update— it prints✓ Already up to date!and completes the remaining stages (launcher refresh, gateway restart). Don't assume failure from an interrupted run. - Long builds exceed foreground command limits: run
hermes updateor rebuilds withterminal(background=true, notify_on_complete=true).
Desktop App Rebuild Must Be Detached
The trap: hermes desktop --build-only stops running desktop instances
during packaging (⚠ Stopped running desktop app to free the build output).
If you launch it from inside the desktop app's own agent session, the agent's
process dies with the app and the build dies mid-npm-install. The process list
goes empty with no error and the old exe/stamp stays in place.
Verified fix (Windows) — detach via a scheduled task so it survives the
app restart (full script in scripts/rebuild-desktop.bat):
- Write a bat that cd's to the install dir, runs
venv\Scripts\hermes.exe desktop --build-onlyredirecting output tologs/desktop-rebuild.log, appends arebuild-finished exit=%ERRORLEVEL%line, and self-deletes the task. - Register and fire it:
schtasks /Create /TN "HermesDesktopRebuild" /TR "\"<path>\rebuild-desktop.bat\"" /SC ONCE /ST 23:59 /F schtasks /Run /TN "HermesDesktopRebuild" - Poll
logs/desktop-rebuild.loguntil therebuild-finishedline appears (npm install + vite + electron-builder takes several minutes; the app window WILL close during packaging — warn the user first).
Verification (do not trust "it ran"):
from hermes_cli.main import _desktop_build_needed, _desktop_packaged_executable
print(_desktop_build_needed(Path('apps/desktop'), Path('.').resolve(), source_mode=False)) # want False
print(_desktop_packaged_executable(Path('apps/desktop'))) # exe mtime should be fresh
The stamp at $LOCALAPPDATA/hermes/desktop-build-stamp.json (builtAt) should
also be current. Note _desktop_build_needed lives in hermes_cli/main.py,
not hermes_cli/update_cmd.py.
reasoning_effort HTTP 400 (Config Rejection Class)
Symptom: new sessions fail immediately with
HTTP 400 ... 'reasoning_effort' must be one of: 'none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'
while older/existing sessions keep working.
Root-cause class: effort-level pass-through vs. conversion. Hermes converts
non-wire levels per adapter — Anthropic maps ultra→budgeted max, gpt-5.6 maps
ultra→max, Gemini clamps to low/medium/high — but the custom provider
profile passes effort verbatim as top-level reasoning_effort
(plugins/model-providers/custom/__init__.py). Any endpoint that doesn't accept
the level (qwen/token-plan DashScope accepts only none…max) rejects with 400.
Why only NEW sessions fail: config is read at session start and frozen for the conversation (prompt caching) — open sessions keep the old value; the first fresh session transmits the bad value. So "it broke on new session" points at a config value, not the update itself.
Fix: check agent.reasoning_effort in ~/.hermes/config.yaml against the
allowed list the error message itself prints; for qwen/alibaba endpoints use
max or below (hermes config set agent.reasoning_effort max in a foreground
session). Generalization: when ANY provider rejects a model param with an enum
error, compare the config value to the printed allowed set, and check whether
the provider plugin converts the value or passes it through.
Desktop Feature "Missing" After an Update
Users often report UI features "disappeared" after an update. Before assuming a regression, check whether the feature is hidden-by-state: the desktop app hides chrome whenever the state that drives it is empty.
Session tabs (browser-like tab bar) are the recurring case. The tab
strip in the main zone only renders once at least one session is open as
a tab; after an app restart the window boots to a single main chat and
the strip is invisible, so the user concludes tabs were removed. The
feature is intact — restore with: session row ⋯ menu → "Open in new
tab", Ctrl+T (fresh session as tab), or the + button on the
strip. Keybinds: Ctrl+Tab cycle, Ctrl+1–9 jump, Ctrl+W close. Full
walkthrough + verification via computer_use:
references/desktop-session-tabs.md.
Verification
hermes version→ "Up to date";hermes gateway status→ process running.- After desktop rebuild: stamp
builtAtfresh,_desktop_build_neededFalse, newHermes.exemtime, app relaunches on the new build. - After config fix: user opens a new session without the 400.