Gateway restart is impossible from inside the gateway; updater leaves it manual
Date: 2026-09-16
Lane: hermes
Source: observed on Zappo (macbook-pro-3, 100.80.168.13) during hermes_openclaw_auto_upgrade.py --apply
What happened
hermes_openclaw_auto_upgrade.py --apply ran hermes update --yes --backup. The update pulled
2156 commits and rebuilt the checkout correctly (v0.21.1 -> v0.21.3, HEAD f97a4102dd ->
5d59366010), then reported:
⚠ Update incomplete — gateway auto-restart failed: cannot import name 'file_signature' from 'utils'
Any gateway still running is serving pre-update code (mixed sys.modules) against the updated checkout.
The import error is a red herring for the code state. from utils import file_signature succeeds
in the updated checkout when tested directly; utils.py:38 defines file_signature. The failure
is a stale sys.modules artifact in the running (old) gateway process, exactly what the message
describes.
Result state: checkout at 5d59366010 (v0.21.3), live gateway still stamping
code_version: 0.21.1, code_sha: f97a4102dd in ~/.hermes/gateway_state.json. The updater left
~/.hermes/fleet_restart_pending with expected_sha=5d59366010... and classified the restart
mechanism as manual.
The blocking fact
A gateway restart cannot be issued from a process descended from the gateway. hermes gateway restart inside the gateway returns:
Blocked: command or referenced script cannot restart, stop, or uninstall the gateway from inside the gateway process. The gateway would kill this command before it could complete (SIGTERM propagates to child processes).
launchctl submit/bootstrap is blocked by the same guard regardless of job label. The guard is
deliberate and must not be worked around. When the updater itself is launched as a background
process from a gateway session, it inherits the gateway's process tree, so the restart phase is
classified manual and never runs.
Rules
- Run the auto-upgrade outside the gateway process tree, or accept that the restart stays manual.
A
terminal(background=true)process spawned from a gateway session is still a gateway descendant and does not escape the guard. - Never treat "update exit=1" as a failed upgrade. Read
~/.hermes/logs/update.log: the pull phase can fully succeed and only the restart phase fail. Confirm the checkout withgit -C ~/.hermes/hermes-agent rev-parse --short HEAD. - Verify a completed upgrade by comparing
code_version/code_shain~/.hermes/gateway_state.jsonagainst the checkout. Equal versions is the only healthy state; a stale gateway is a mixed-version fleet. ~/.hermes/fleet_restart_pendingpresent means a restart is owed. It is cleared by a successful restart, not by hand.- The gateway must be restarted from a terminal outside the gateway (a plain login shell, not a
Hermes session), then verified with
hermes gateway status.
OpenClaw is gated on Node, not on the updater
OpenClaw could not update: Node 22.22.3 is too old for openclaw@2026.9.4. The requested package requires >=24.16.0 \<25 || >=26.1.0. Both /usr/local/bin/node and the Node that OpenClaw runs
under (~/.npm-global/lib/node_modules/node/bin/node) are v22.22.3. The Node upgrade is a
separate, previously flagged decision. Until then OpenClaw stays on 2026.8.1. Do not run bare
npm i -g openclaw as a workaround; it can silently install an older compatible release.