Skip to content

fix(desktop): retry the self-update rebuild once so the app relaunches - #48122

Merged
OutThisLife merged 1 commit into
mainfrom
hermes/desktop-update-rebuild-retry
Jun 18, 2026
Merged

fix(desktop): retry the self-update rebuild once so the app relaunches#48122
OutThisLife merged 1 commit into
mainfrom
hermes/desktop-update-rebuild-retry

Conversation

@OutThisLife

Copy link
Copy Markdown
Collaborator

Summary

Fast-follow to #48091 (the desktop Electron self-heal). Field report after that merged: an update that triggered a from-scratch reinstall rebuilt fine but didn't relaunch — the app was updated and worked when launched manually.

Root cause: the desktop self-update runs hermes updatehermes desktop --build-only → relaunch, and only relaunches if the rebuild returns 0. The first --build-only can exit nonzero on a still-settling post-update tree, or on a network-blocked Electron fetch that #48091's self-heal repaired mid-run. Both updaters then bail before the relaunch step:

  • apps/bootstrap-installer/src-tauri/src/update.rs (Tauri setup binary): rebuild nonzero → return Err before launch_macos_app_and_exit.
  • apps/desktop/electron/main.cjs applyUpdatesPosixInApp (mac/linux drag-install): rebuild nonzero → early return before the swap+open.

The hermes update stage already retries once in both updaters, and the CLI hermes update's own desktop rebuild retries once (hermes_cli/main.py) — the --build-only rebuild stage was the one path that didn't. This adds that same retry-once.

A second --build-only builds clean off the healed dist and is a near-no-op when the first actually succeeded (the content-hash stamp short-circuits). The happy path (first build returns 0) is unchanged.

Changes

  • update.rs — retry stage 2 once before failing; extract rebuild_needs_retry() + unit test.
  • main.cjs — retry via a new electron/update-rebuild.cjs helper (runRebuildWithRetry / shouldRetryRebuild), behavior-tested with an injected runner; wired update-rebuild.test.cjs into test:desktop:platforms.

Test plan

  • cargo test rebuild_retries_only_on_failure → ok (retry on Some(1)/None, not on Some(0)).
  • node --test electron/update-rebuild.test.cjs → 4 passing (no-retry on success; retry-then-succeed; at-most-twice on persistent failure; predicate contract).
  • node -c electron/main.cjs clean.
  • Pre-existing macOS-only failure update::tests::lock_probe_paths_include_desktop_app_payload is unrelated (fails identically on clean origin/main).

The desktop self-update runs `hermes update` then `hermes desktop
--build-only`, and only relaunches if the rebuild returns 0. The first
`--build-only` can exit nonzero on a still-settling post-update tree or a
network-blocked Electron fetch that the installer's self-heal repaired
mid-run — so both updaters (the Tauri setup binary and the in-app POSIX
path) bailed before the relaunch step. The update landed but the app
never restarted; a manual launch worked because the heal had completed.

Retry `--build-only` once in both paths before failing, mirroring the
retry-once `hermes update` already does (and the CLI `hermes update`'s
own desktop rebuild). A second run builds clean off the healed dist and
is a near-no-op when the first actually succeeded (content-hash stamp).

- update.rs: retry stage 2; add rebuild_needs_retry() + test
- main.cjs: retry via new update-rebuild.cjs helper (behavior-tested)
@OutThisLife
OutThisLife requested a review from a team June 18, 2026 00:14
@github-actions

Copy link
Copy Markdown
Contributor

🔎 Lint report: hermes/desktop-update-rebuild-retry vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 10984 on HEAD, 10986 on base (✅ -2)

🆕 New issues (1):

Rule Count
invalid-assignment 1
First entries
tests/run_agent/test_credits_notices_toggle.py:76: [invalid-assignment] invalid-assignment: Object of type `None` is not assignable to attribute `_credits_session_start_micros` of type `int`

✅ Fixed issues (2):

Rule Count
unresolved-attribute 2
First entries
tests/run_agent/test_credits_notices_toggle.py:76: [unresolved-attribute] unresolved-attribute: Unresolved attribute `_credits_session_start_micros` on type `AIAgent`
run_agent.py:2941: [unresolved-attribute] unresolved-attribute: Object of type `Self@get_credits_spent_micros` has no attribute `_credits_session_start_micros`

Unchanged: 5751 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/tui Terminal UI (ui-tui/ + tui_gateway/) labels Jun 18, 2026
@OutThisLife
OutThisLife merged commit 4b7a186 into main Jun 18, 2026
35 checks passed
@OutThisLife
OutThisLife deleted the hermes/desktop-update-rebuild-retry branch June 18, 2026 00:33
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
NousResearch#48122)

The desktop self-update runs `hermes update` then `hermes desktop
--build-only`, and only relaunches if the rebuild returns 0. The first
`--build-only` can exit nonzero on a still-settling post-update tree or a
network-blocked Electron fetch that the installer's self-heal repaired
mid-run — so both updaters (the Tauri setup binary and the in-app POSIX
path) bailed before the relaunch step. The update landed but the app
never restarted; a manual launch worked because the heal had completed.

Retry `--build-only` once in both paths before failing, mirroring the
retry-once `hermes update` already does (and the CLI `hermes update`'s
own desktop rebuild). A second run builds clean off the healed dist and
is a near-no-op when the first actually succeeded (content-hash stamp).

- update.rs: retry stage 2; add rebuild_needs_retry() + test
- main.cjs: retry via new update-rebuild.cjs helper (behavior-tested)
habarmc1223-sudo pushed a commit to habarmc1223-sudo/hermes-agent-fluxmem that referenced this pull request Jul 8, 2026
NousResearch#48122)

The desktop self-update runs `hermes update` then `hermes desktop
--build-only`, and only relaunches if the rebuild returns 0. The first
`--build-only` can exit nonzero on a still-settling post-update tree or a
network-blocked Electron fetch that the installer's self-heal repaired
mid-run — so both updaters (the Tauri setup binary and the in-app POSIX
path) bailed before the relaunch step. The update landed but the app
never restarted; a manual launch worked because the heal had completed.

Retry `--build-only` once in both paths before failing, mirroring the
retry-once `hermes update` already does (and the CLI `hermes update`'s
own desktop rebuild). A second run builds clean off the healed dist and
is a near-no-op when the first actually succeeded (content-hash stamp).

- update.rs: retry stage 2; add rebuild_needs_retry() + test
- main.cjs: retry via new update-rebuild.cjs helper (behavior-tested)
santhreal pushed a commit to santhreal/hermes-agent that referenced this pull request Jul 13, 2026
NousResearch#48122)

The desktop self-update runs `hermes update` then `hermes desktop
--build-only`, and only relaunches if the rebuild returns 0. The first
`--build-only` can exit nonzero on a still-settling post-update tree or a
network-blocked Electron fetch that the installer's self-heal repaired
mid-run — so both updaters (the Tauri setup binary and the in-app POSIX
path) bailed before the relaunch step. The update landed but the app
never restarted; a manual launch worked because the heal had completed.

Retry `--build-only` once in both paths before failing, mirroring the
retry-once `hermes update` already does (and the CLI `hermes update`'s
own desktop rebuild). A second run builds clean off the healed dist and
is a near-no-op when the first actually succeeded (content-hash stamp).

- update.rs: retry stage 2; add rebuild_needs_retry() + test
- main.cjs: retry via new update-rebuild.cjs helper (behavior-tested)
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
NousResearch#48122)

The desktop self-update runs `hermes update` then `hermes desktop
--build-only`, and only relaunches if the rebuild returns 0. The first
`--build-only` can exit nonzero on a still-settling post-update tree or a
network-blocked Electron fetch that the installer's self-heal repaired
mid-run — so both updaters (the Tauri setup binary and the in-app POSIX
path) bailed before the relaunch step. The update landed but the app
never restarted; a manual launch worked because the heal had completed.

Retry `--build-only` once in both paths before failing, mirroring the
retry-once `hermes update` already does (and the CLI `hermes update`'s
own desktop rebuild). A second run builds clean off the healed dist and
is a near-no-op when the first actually succeeded (content-hash stamp).

- update.rs: retry stage 2; add rebuild_needs_retry() + test
- main.cjs: retry via new update-rebuild.cjs helper (behavior-tested)
leewenjie pushed a commit to leewenjie/hermes-agent that referenced this pull request Aug 7, 2026
NousResearch#48122)

The desktop self-update runs `hermes update` then `hermes desktop
--build-only`, and only relaunches if the rebuild returns 0. The first
`--build-only` can exit nonzero on a still-settling post-update tree or a
network-blocked Electron fetch that the installer's self-heal repaired
mid-run — so both updaters (the Tauri setup binary and the in-app POSIX
path) bailed before the relaunch step. The update landed but the app
never restarted; a manual launch worked because the heal had completed.

Retry `--build-only` once in both paths before failing, mirroring the
retry-once `hermes update` already does (and the CLI `hermes update`'s
own desktop rebuild). A second run builds clean off the healed dist and
is a near-no-op when the first actually succeeded (content-hash stamp).

- update.rs: retry stage 2; add rebuild_needs_retry() + test
- main.cjs: retry via new update-rebuild.cjs helper (behavior-tested)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/tui Terminal UI (ui-tui/ + tui_gateway/) P3 Low — cosmetic, nice to have type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants