Skip to content

Chat tab fails with "Chat unavailable: 1" on pip/pipx install — ui-tui workspace check runs before bundled-wheel fallback #56665

Description

@lucaskvasirr

Summary

Dashboard's embedded Chat tab fails with "Chat unavailable: 1" on a plain pip/pipx install (no Docker, no git checkout). Root cause: _make_tui_argv() calls _ensure_tui_workspace(tui_dir) unconditionally before checking for a prebuilt bundle, and that function hard-exits with sys.exit(1) when ui-tui/ doesn't exist — which it never does in a pip/pipx install, since the wheel doesn't ship that directory at all (confirmed 0 matches for ui-tui in hermes_agent-0.18.0.dist-info/RECORD). The bundled fallback (hermes_cli/tui_dist/entry.js, which is shipped in the wheel and is fully valid) is never reached because the workspace check runs first and kills the process.

This looks related to #20500 and #20739, but those are Docker-image permission bugs (root-owned ui-tui/, EACCES on write). This one has no ui-tui/ directory at all, because it's a pip/pipx install rather than the Docker image or a git checkout — different trigger, same downstream symptom and same SystemExit(1)"Chat unavailable: 1" swallow point in pty_ws.

Environment

  • Hermes Agent version: v0.18.0 (2026.7.1) — hermes version
  • Install method: pipx install hermes-agent (wheel from PyPI, not Docker, not git checkout)
  • Python: 3.12.3
  • OS: Ubuntu 24.04.4 LTS, kernel 6.17.0-1011-oracle, aarch64
  • Node: v22.23.1 / npm 10.9.8 (both present and on PATH — ruled out as the cause)

Steps to reproduce

  1. Install via pipx: pipx install hermes-agent
  2. Start the dashboard: hermes dashboard --no-open --host 0.0.0.0 --port 9119
  3. Open the dashboard in a browser and connect to the embedded Chat tab (/api/pty websocket)
  4. Banner shows: Chat unavailable: 1

Confirmed root cause

$ ls -la /home/ubuntu/.local/share/pipx/venvs/hermes-agent/lib/python3.12/site-packages/ui-tui
ls: cannot access '.../site-packages/ui-tui': No such file or directory

$ grep -c "ui-tui" .../hermes_agent-0.18.0.dist-info/RECORD
0

Dashboard stdout at the moment of failure:

Error: the TUI workspace is missing from this Hermes checkout.
Expected directory: /home/ubuntu/.local/share/pipx/venvs/hermes-agent/lib/python3.12/site-packages/ui-tui
This usually means `hermes update` left tracked ui-tui files deleted.
Recovery:
  1. From the Hermes checkout, run `git restore -- ui-tui`
  2. Run `npm install --silent --no-fund --no-audit --progress=false`
  3. Retry `hermes --tui`
If the checkout is still inconsistent, run `hermes update --force`.

The recovery instructions assume a git checkout (git restore), which doesn't apply to a pip/pipx install — there's no .git here, so this guidance is a dead end for this install method.

Relevant code path in hermes_cli/main.py, _make_tui_argv():

if not ext_dir:
    _ensure_tui_workspace(tui_dir)   # <-- unconditional, runs BEFORE the bundled-bundle check below

# 1. Prebuilt bundle (nix / packaged release): just run it.
if not tui_dev:
    if ext_dir:
        ...
    # 1b. Bundled in wheel (pip install)
    bundled = _find_bundled_tui()   # <-- this succeeds; hermes_cli/tui_dist/entry.js exists and is valid
    if bundled is not None:
        node = _node_bin("node")
        return [node, "--expose-gc", str(bundled)], bundled.parent

_ensure_tui_workspace (also in hermes_cli/main.py) is the one that hard-exits:

def _ensure_tui_workspace(tui_dir: Path) -> None:
    if tui_dir.is_dir():
        return
    if _restore_tui_workspace(tui_dir):
        ...
        return
    print("Error: the TUI workspace is missing from this Hermes checkout. ...")
    sys.exit(1)

Confirmed the bundled entry.js is present and intact and never gets a chance to run:

$ ls -la .../hermes_cli/tui_dist/entry.js
-rwxrwxr-x 1 ubuntu ubuntu 3469948 Jul  1 20:16 .../hermes_cli/tui_dist/entry.js

The SystemExit(1) propagates up to pty_ws in hermes_cli/web_server.py, which catches it and sends the unhelpful Chat unavailable: {exc} (i.e., Chat unavailable: 1) over the websocket with no further detail, so the real cause never reaches the browser or any log the end user would think to check.

Suggested fix

Reorder the checks in _make_tui_argv() so the bundled-wheel shortcut (_find_bundled_tui()) is tried before _ensure_tui_workspace() runs. The workspace check should only be a hard requirement for the git-checkout / dev-mode path, not for a packaged pip/pipx install that ships a working prebuilt bundle and has no ui-tui/ source tree by design.

As a secondary improvement (also flagged in #20739): pty_ws swallowing SystemExit into a bare Chat unavailable: {exc} hides the actual error from the user. Printing/logging the pre-sys.exit message server-side is already happening (it showed up in the dashboard's stdout in my case), but surfacing at least a pointer to "check the dashboard process's stdout/log" in the websocket message would save the next person the trial and error.

Workaround

Manually creating an empty ui-tui/ directory at the expected path makes _ensure_tui_workspace a no-op (tui_dir.is_dir() returns True) and lets execution fall through to _find_bundled_tui(), which then succeeds. Not proposing this as the fix — just confirms the diagnosis.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium — degraded but workaround existsarea/install-updateInstaller, updater, packaging, wheels, doctorcomp/cliCLI entry point, hermes_cli/, setup wizardcomp/dashboardWeb dashboard / control panel UI (dashboard/, landing)type/bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions