Skip to content

fix(update): GUI update self-deadlocks against its own lock — every retry fails with "Hermes is still running" - #74630

Merged
OutThisLife merged 1 commit into
mainfrom
bb/update-restart-race
Jul 30, 2026
Merged

fix(update): GUI update self-deadlocks against its own lock — every retry fails with "Hermes is still running"#74630
OutThisLife merged 1 commit into
mainfrom
bb/update-restart-race

Conversation

@OutThisLife

@OutThisLife OutThisLife commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Any install whose checkout already carries the cross-process update lock (fe8e4d9, merged yesterday) self-deadlocks on its next GUI → Update Hermes: the Tauri updater claims the update-in-progress marker for its whole run, then spawns hermes update as a child stage — which reads the marker, finds its own parent's live pid, and refuses with exit 2. The GUI surfaces that as "Hermes is still running. Close all Hermes windows and try the update again", and Retry launches a fresh updater that deadlocks against itself the same way.

The rollout shape hides it for one cycle: the child checks the lock from disk code before pulling, so the first update after fe8e4d9 landed still runs the pre-lock child and succeeds — it's the update after that which dead-ends. Observed exactly that way in bootstrap-installer.log: a clean update at 04:44 UTC (the one that installed the lock code), then three consecutive self-refusals (PIDs 86193 → 86854 → 87252) starting 05:42, each refusing its own parent's marker.

The fix hands the claim off explicitly instead of weakening the lock: update_child_env exports HERMES_UPDATE_HANDOFF_PID naming the updater's own pid, and UpdateLock.acquire treats a live holder matching that pid as the lock we're already running under — the child runs without claiming, and release leaves the parent's marker untouched for the remaining rebuild/install stages. The env var alone grants nothing: the pid must also be the live marker's owner, so a stale or forged value can't bypass the lock, and a dashboard-spawned hermes update (no handoff env) is still refused exactly as the original fix intended.

…it already holds

The cross-process update lock (fe8e4d9) made the in-progress marker
mutually exclusive across every update entrypoint — but the Tauri
updater holds that marker for its WHOLE run and then spawns
hermes update as a child stage. The child read the marker, found its
own parent's live pid, refused with exit 2, and the GUI mapped that to
"Hermes is still running. Close all Hermes windows and try the update
again." Retry spawns a fresh updater that deadlocks against itself the
same way, so every GUI-driven update dead-ends on the failure screen
with no winnable retry (observed: three consecutive self-refusals in
bootstrap-installer.log within 90 seconds).

Hand the claim off explicitly: update_child_env exports
HERMES_UPDATE_HANDOFF_PID naming the updater's own pid, and
UpdateLock.acquire treats a live holder matching that pid as the lock
we are already running under — run without claiming, and release
leaves the parent's marker untouched. The env var alone grants
nothing: the pid must also be the live marker owner, so a stale or
forged value cannot bypass the lock, and a dashboard-spawned
hermes update (no handoff env) is still refused exactly as before.
@OutThisLife
OutThisLife enabled auto-merge July 30, 2026 05:56
@alt-glitch alt-glitch added type/bug Something isn't working comp/desktop Electron desktop app (apps/desktop/*) comp/cli CLI entry point, hermes_cli/, setup wizard platform/windows Native Windows-specific behavior or breakage area/install-update Installer, updater, packaging, wheels, doctor sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades P1 High — major feature broken, no workaround labels Jul 30, 2026
@github-actions

Copy link
Copy Markdown
Contributor

૮ >ﻌ< ა ci review

ran on 8c76fe1

ℹ️ Info

Desktop E2E visual evidence · View test artifacts · View job

1 visual diff.

inline evidence is publishing...

@OutThisLife
OutThisLife merged commit fa8b959 into main Jul 30, 2026
50 checks passed
@OutThisLife
OutThisLife deleted the bb/update-restart-race branch July 30, 2026 06:43
randlee pushed a commit to randlee/hermes-agent that referenced this pull request Aug 11, 2026
…tart-race

fix(update): GUI update self-deadlocks against its own lock — every retry fails with "Hermes is still running"
33hodl pushed a commit to 33hodl/hermes-agent that referenced this pull request Aug 12, 2026
…tart-race

fix(update): GUI update self-deadlocks against its own lock — every retry fails with "Hermes is still running"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/install-update Installer, updater, packaging, wheels, doctor comp/cli CLI entry point, hermes_cli/, setup wizard comp/desktop Electron desktop app (apps/desktop/*) P1 High — major feature broken, no workaround platform/windows Native Windows-specific behavior or breakage sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants