hermes - 💡(How to fix) Fix Update Now can show success/restart without applying any update when no targets are selected

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Error Message

If no update targets are selected, the UI should not claim success or start the restart wait flow. It should show an actionable error and reset the button. else showToast(msg,5000,'error');

Root Cause

In /app/static/ui.js, applyUpdates() builds its target list from window._updateData:

const targets=[];
if(window._updateData?.webui?.behind>0) targets.push('webui');
if(window._updateData?.agent?.behind>0) targets.push('agent');

But if targets is empty, execution still falls through to:

showToast('Update applied — restarting…');
sessionStorage.removeItem('hermes-update-checked');
sessionStorage.removeItem('hermes-update-dismissed');
_waitForServerThenReload();

So stale/missing update data, a cache race, or any case where the banner/button remains visible while window._updateData has no behind > 0 targets can produce a false-success update.

Code Example

const targets=[];
if(window._updateData?.webui?.behind>0) targets.push('webui');
if(window._updateData?.agent?.behind>0) targets.push('agent');

---

showToast('Update applied — restarting…');
sessionStorage.removeItem('hermes-update-checked');
sessionStorage.removeItem('hermes-update-dismissed');
_waitForServerThenReload();

---

if(!targets.length){
  const msg='No update target selected. Refresh update status and retry.';
  if(errEl){errEl.textContent=msg;errEl.style.display='block';}
  else showToast(msg,5000,'error');
  resetApplyButton(0);
  return;
}

---

Update applied — restarting…
RAW_BUFFERClick to expand / collapse

Bug description

The WebUI Update Now button can show Update applied — restarting… and enter the restart/reload wait flow even when it sends zero /api/updates/apply requests.

This makes it look like the update succeeded, but no git pull is actually attempted.

Root cause

In /app/static/ui.js, applyUpdates() builds its target list from window._updateData:

const targets=[];
if(window._updateData?.webui?.behind>0) targets.push('webui');
if(window._updateData?.agent?.behind>0) targets.push('agent');

But if targets is empty, execution still falls through to:

showToast('Update applied — restarting…');
sessionStorage.removeItem('hermes-update-checked');
sessionStorage.removeItem('hermes-update-dismissed');
_waitForServerThenReload();

So stale/missing update data, a cache race, or any case where the banner/button remains visible while window._updateData has no behind > 0 targets can produce a false-success update.

Expected behavior

If no update targets are selected, the UI should not claim success or start the restart wait flow. It should show an actionable error and reset the button.

Example guard:

if(!targets.length){
  const msg='No update target selected. Refresh update status and retry.';
  if(errEl){errEl.textContent=msg;errEl.style.display='block';}
  else showToast(msg,5000,'error');
  resetApplyButton(0);
  return;
}

Actual behavior

The UI can show:

Update applied — restarting…

without sending any apply request or running any git command.

Why this matters

This is confusing for self-update troubleshooting. It makes browser cache/proxy/reload behavior look like a git/update failure, when the backend may never have been called.

Observed during troubleshooting:

  • manual git pull --ff-only origin main worked as UID 1000
  • repo permissions were correct
  • backend apply_update("agent") worked when invoked directly
  • git reflog showed no HEAD movement from the WebUI button attempt
  • frontend code allowed a zero-target false success

Environment

  • Hermes WebUI version: v0.51.130
  • Agent checkout path: /home/hermes/.hermes/hermes-agent
  • WebUI process UID/GID: 1000:1000
  • Static JS is served with long immutable cache headers, which can make the false-success state harder to distinguish from browser/proxy cache issues.

Suggested fix

Add an early guard in applyUpdates() after target selection so the function returns before displaying success/restart if targets.length === 0.

Optional follow-up: add lightweight backend logging around /api/updates/apply so failed/blocked update attempts are visible in logs.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

If no update targets are selected, the UI should not claim success or start the restart wait flow. It should show an actionable error and reset the button.

Example guard:

if(!targets.length){
  const msg='No update target selected. Refresh update status and retry.';
  if(errEl){errEl.textContent=msg;errEl.style.display='block';}
  else showToast(msg,5000,'error');
  resetApplyButton(0);
  return;
}

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - 💡(How to fix) Fix Update Now can show success/restart without applying any update when no targets are selected