hermes - 💡(How to fix) Fix dashboard: exit code 1 with no fallback when web UI build fails in non-interactive context (Windows Scheduled Task)

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…

When Hermes Dashboard is registered as a Windows Scheduled Task (LogonTrigger + InteractiveToken) and runs automatically at user logon, it exits with code 1 if the Vite web UI build fails — leaving port 9119 unreachable. The same build succeeds when run manually from an interactive terminal.

This is not a PATH or S4U issue (the task uses correct InteractiveToken with full user environment). The problem is architectural: the Dashboard has no fallback or retry when its internal npm run build fails.

Error Message

Additionally, the npm build failure details (stderr) are not surfaced in the dashboard startup log — the error message just says ✗ Web UI build failed with no information about why. Adding the captured stderr to the log output would significantly improve debugging.

Root Cause

In hermes_cli/main.py, the startup flow is:

start()
  → _web_ui_build_needed()      # checks if dist is missing or stale
  → _build_web_ui()              # runs npm run build via subprocess
  → start HTTP server            # never reached if build fails

Three specific gaps:

  1. No --skip-build / --prebuilt flag — the caller cannot tell the Dashboard "the dist is already built, don't try to build." A Windows Scheduled Task could then pre-build in the BAT wrapper and start the Dashboard with --skip-build, avoiding the internal build entirely.

  2. No fallback to stale dist — if web_dist/index.html exists but is stale (source files modified), the Dashboard could serve the stale version and let the user refresh after a manual build, rather than exiting with code 1. Many CI/CD systems (including npm run build output resolution across machines) produce identical build artifacts; a stale UI is far better than no UI.

  3. No retry_build_web_ui() calls subprocess.run() once. If it fails (e.g. npm not fully initialized at boot, antivirus scanning Node.js binaries, transient disk I/O), the process exits immediately. A simple 1-retry with a 3-second delay would cover most boot-time race conditions.

Additionally, the npm build failure details (stderr) are not surfaced in the dashboard startup log — the error message just says ✗ Web UI build failed with no information about why. Adding the captured stderr to the log output would significantly improve debugging.

Fix Action

Fix / Workaround

Workaround (for users hitting this)

Code Example

start()
_web_ui_build_needed()      # checks if dist is missing or stale
_build_web_ui()              # runs npm run build via subprocess
  → start HTTP server            # never reached if build fails

---

set WEB_DIR=%LOCALAPPDATA%\hermes\hermes-agent\web
cd /d "%WEB_DIR%"
npm run build >nul 2>&1
if %ERRORLEVEL% neq 0 (
    timeout /t 3 /nobreak >nul
    npm run build >nul 2>&1
)
cd /d "%~dp0"
RAW_BUFFERClick to expand / collapse

Description

When Hermes Dashboard is registered as a Windows Scheduled Task (LogonTrigger + InteractiveToken) and runs automatically at user logon, it exits with code 1 if the Vite web UI build fails — leaving port 9119 unreachable. The same build succeeds when run manually from an interactive terminal.

This is not a PATH or S4U issue (the task uses correct InteractiveToken with full user environment). The problem is architectural: the Dashboard has no fallback or retry when its internal npm run build fails.

Steps to Reproduce

  1. Install Hermes on Windows 11
  2. Register Dashboard as a Scheduled Task (correctly configured: LogonTrigger + InteractiveToken, via VBS wrapper)
  3. Reboot, or run hermes update (which replaces web source files)
  4. Access http://127.0.0.1:9119 → connection refused
  5. Check ~/.hermes/dashboard-startup.log → shows ✗ Web UI build failed

Expected Behavior

The Dashboard should handle web UI build failures gracefully:

  • If a stale web_dist/ exists, serve it as a fallback (better than nothing)
  • Or retry the build once before giving up
  • Or accept a --skip-build / --prebuilt flag so the caller can guarantee the dist is ready

Actual Behavior

Dashboard exits with code 1. HTTP server is never started. The only way to recover is to manually cd web && npm run build in a terminal, then restart.

Root Cause

In hermes_cli/main.py, the startup flow is:

start()
  → _web_ui_build_needed()      # checks if dist is missing or stale
  → _build_web_ui()              # runs npm run build via subprocess
  → start HTTP server            # never reached if build fails

Three specific gaps:

  1. No --skip-build / --prebuilt flag — the caller cannot tell the Dashboard "the dist is already built, don't try to build." A Windows Scheduled Task could then pre-build in the BAT wrapper and start the Dashboard with --skip-build, avoiding the internal build entirely.

  2. No fallback to stale dist — if web_dist/index.html exists but is stale (source files modified), the Dashboard could serve the stale version and let the user refresh after a manual build, rather than exiting with code 1. Many CI/CD systems (including npm run build output resolution across machines) produce identical build artifacts; a stale UI is far better than no UI.

  3. No retry_build_web_ui() calls subprocess.run() once. If it fails (e.g. npm not fully initialized at boot, antivirus scanning Node.js binaries, transient disk I/O), the process exits immediately. A simple 1-retry with a 3-second delay would cover most boot-time race conditions.

Additionally, the npm build failure details (stderr) are not surfaced in the dashboard startup log — the error message just says ✗ Web UI build failed with no information about why. Adding the captured stderr to the log output would significantly improve debugging.

Workaround (for users hitting this)

Add a pre-build step in the BAT startup script before calling hermes dashboard:

set WEB_DIR=%LOCALAPPDATA%\hermes\hermes-agent\web
cd /d "%WEB_DIR%"
npm run build >nul 2>&1
if %ERRORLEVEL% neq 0 (
    timeout /t 3 /nobreak >nul
    npm run build >nul 2>&1
)
cd /d "%~dp0"

This builds the web UI in the BAT's environment (which has full PATH) before the Dashboard tries to do it internally. Since _web_ui_build_needed() checks source file mtimes vs dist, the internal build is skipped if the dist is already fresh.

Environment

  • Windows 11 (version 10.0.26200.8328)
  • Hermes latest (git checkout)
  • Node.js v24.15.0, npm 11.12.1
  • Scheduled Task: LogonTrigger + InteractiveToken (correct configuration)

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…

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 dashboard: exit code 1 with no fallback when web UI build fails in non-interactive context (Windows Scheduled Task)