Skip to content

fix(dashboard): fallback to stale dist, retry build, add --skip-build flag#23859

Merged
teknium1 merged 2 commits into
mainfrom
hermes/hermes-1b178157
May 11, 2026
Merged

fix(dashboard): fallback to stale dist, retry build, add --skip-build flag#23859
teknium1 merged 2 commits into
mainfrom
hermes/hermes-1b178157

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Salvages #23824 by @ygd58 with two correctness fixes folded in.

Fixes #23817 — Windows Scheduled Task starts the dashboard at logon, npm build fails in the non-interactive environment, and the dashboard exits with no fallback. Port 9119 stays unreachable until the user manually rebuilds.

Changes

hermes_cli/main.py:

  • _build_web_ui: retry npm run build once after 3s (covers boot-time races on Windows — antivirus scanning Node.js, npm cache not ready, transient I/O).
  • _build_web_ui: if the build still fails AND a stale web_dist/index.html exists, serve it as a fallback. A stale UI is far better than no UI for non-interactive callers.
  • _build_web_ui: surface the npm stderr tail (last 10 lines) in the failure message — previously the user just saw "✗ Web UI build failed" with no clue why.
  • cmd_dashboard: add --skip-build flag for callers that pre-build (e.g. a BAT wrapper around the Scheduled Task). When set, validate that the dist actually exists before starting the server, so a misconfigured pre-build exits 1 with clear guidance instead of silently serving 404s.

tests/hermes_cli/test_web_ui_build.py:

  • 3 new tests — retry path, stale-dist fallback (with fatal=True, which is the issue's primary scenario), and hard-fail when no dist exists.

Salvage notes

@ygd58's PR had a Python SyntaxError (literal newline mid-string in the \"\\n \".join(...)) and gated the stale-dist fallback on not fatal — but cmd_dashboard always passes fatal=True, so the fallback never fired in the exact scenario the issue is about. Both fixed in the cherry-pick. Followup commit adds the --skip-build dist-existence sanity check + tests.

Validation

Result
tests/hermes_cli/test_web_ui_build.py 16/16 passed (13 pre-existing + 3 new)
tests/hermes_cli/test_dashboard_* 24/24 passed
E2E: build fails + stale dist (fatal=True) fallback fires, stderr surfaced
E2E: build fails + no dist (fatal=True) exit 1 with stderr + "Run manually"
E2E: --skip-build + missing dist exit 1 with clear "pre-build first" guidance
E2E: --skip-build + valid dist "→ Skipping web UI build (--skip-build); using dist at ..."

Original PR #23824 will be closed with credit pointing here.

ygd58 and others added 2 commits May 11, 2026 08:18
… flag

Three improvements for non-interactive contexts (Windows Scheduled
Tasks, CI/CD) where the web UI build may fail (issue #23817):

1. Retry build once after 3s — covers boot-time races (antivirus
   scanning Node.js, npm cache not ready, transient disk I/O)
2. Fall back to existing dist when build fails (non-fatal mode) —
   a stale UI is far better than no UI at all
3. Add --skip-build flag — lets callers pre-build in their wrapper
   script and start the dashboard without internal build attempt
4. Surface npm stderr in build failure output for easier debugging

Fixes #23817
Follow-up to PR #23824. Adds two correctness fixes on top of the
contributor's salvaged commit:

1. Stale-dist fallback no longer gated on `fatal=False`. `cmd_dashboard`
   passes `fatal=True` and is the primary scenario this fallback is for
   (issue #23817 — Windows Scheduled Task at logon). The previous gate
   meant the fallback never fired in the case it was designed for.

2. `--skip-build` now verifies the dist actually exists before starting
   the server. Without this, a misconfigured pre-build would launch the
   dashboard pointing at a missing dist and silently serve 404s. We now
   exit 1 with a clear "pre-build first: cd web && npm run build"
   message, and on success print which dist directory is being used.

Verified end-to-end on Linux:
- build fails + stale dist (fatal=True)  -> fallback fires
- build fails + no dist (fatal=True)     -> exit 1 with stderr surfaced
- build fails + stale dist (fatal=False) -> fallback fires
- --skip-build + missing dist            -> exit 1 with clear guidance
- --skip-build + valid dist              -> 'Skipping web UI build...'
@github-actions

Copy link
Copy Markdown
Contributor

🔎 Lint report: hermes/hermes-1b178157 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: 8118 on HEAD, 8118 on base (➖ 0)

🆕 New issues (3):

Rule Count
invalid-argument-type 3
First entries
run_agent.py:13308: [invalid-argument-type] invalid-argument-type: Argument to function `_is_oauth_token` is incorrect: Expected `str`, found `str | dict[Unknown, Unknown] | Any | ... omitted 3 union elements`
run_agent.py:13311: [invalid-argument-type] invalid-argument-type: Argument to function `len` is incorrect: Expected `Sized`, found `(str & ~AlwaysFalsy) | (dict[Unknown, Unknown] & ~AlwaysFalsy) | (Any & ~AlwaysFalsy) | ... omitted 3 union elements`
run_agent.py:7160: [invalid-argument-type] invalid-argument-type: Argument to function `build_anthropic_client` is incorrect: Expected `str`, found `str | dict[Unknown, Unknown] | Any | ... omitted 3 union elements`

✅ Fixed issues (3):

Rule Count
invalid-argument-type 3
First entries
run_agent.py:13308: [invalid-argument-type] invalid-argument-type: Argument to function `_is_oauth_token` is incorrect: Expected `str`, found `str | dict[Unknown | str, Unknown | str | dict[str, str]] | Any | ... omitted 3 union elements`
run_agent.py:13311: [invalid-argument-type] invalid-argument-type: Argument to function `len` is incorrect: Expected `Sized`, found `(str & ~AlwaysFalsy) | (dict[Unknown | str, Unknown | str | dict[str, str]] & ~AlwaysFalsy) | (Any & ~AlwaysFalsy) | ... omitted 3 union elements`
run_agent.py:7160: [invalid-argument-type] invalid-argument-type: Argument to function `build_anthropic_client` is incorrect: Expected `str`, found `str | dict[Unknown | str, Unknown | str | dict[str, str]] | Any | ... omitted 3 union elements`

Unchanged: 4274 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 P2 Medium — degraded but workaround exists comp/cli CLI entry point, hermes_cli/, setup wizard labels May 11, 2026
@teknium1 teknium1 merged commit 283381b into main May 11, 2026
15 of 18 checks passed
@teknium1 teknium1 deleted the hermes/hermes-1b178157 branch May 11, 2026 16:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

dashboard: exit code 1 with no fallback when web UI build fails in non-interactive context (Windows Scheduled Task)

3 participants