hermes - 💡(How to fix) Fix Desktop chat can get stuck busy after idle WebSocket prompt timeout

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…

The Hermes desktop app can lose the active chat flow after the user leaves a session idle/manual for a while and then sends a new message. The composer shows request timed out: prompt.submit, subsequent sends report session busy, and restarting the desktop app clears it.

Root Cause

The desktop JSON-RPC client did not close/reconnect the stale WebSocket when an RPC request timed out. The backend also stored the session transport and could keep routing async session events toward an old socket unless another request explicitly rebound it.

Fix Action

Fix

A PR will be linked here with the solution:

  • close the stale socket when an RPC request times out
  • reconnect based on the gateway client state
  • on prompt.submit timeout, query session.status; if the backend is running, treat the submit as accepted
  • rebind live session transports to the current WebSocket on session-scoped requests
  • add frontend and backend regression tests

Code Example

2026-06-06 01:30:42,474 WARNING tui_gateway.ws: ws response send failed peer=127.0.0.1:59334 id=48 method=prompt.submit
RAW_BUFFERClick to expand / collapse

Summary

The Hermes desktop app can lose the active chat flow after the user leaves a session idle/manual for a while and then sends a new message. The composer shows request timed out: prompt.submit, subsequent sends report session busy, and restarting the desktop app clears it.

Evidence

Local logs showed the backend failing to write the prompt response over the WebSocket:

2026-06-06 01:30:42,474 WARNING tui_gateway.ws: ws response send failed peer=127.0.0.1:59334 id=48 method=prompt.submit

That means prompt.submit may already have been accepted by the backend, while the renderer only sees a request timeout. After that, the UI retries against a session that is correctly still marked running, so user prompts get queued as session busy.

Root cause

The desktop JSON-RPC client did not close/reconnect the stale WebSocket when an RPC request timed out. The backend also stored the session transport and could keep routing async session events toward an old socket unless another request explicitly rebound it.

Expected behavior

After an idle/stale WebSocket, the desktop app should reconnect and keep the live session attached. If prompt.submit times out but the backend accepted the turn, the UI should continue waiting for the running turn instead of surfacing a fake failed prompt.

Fix

A PR will be linked here with the solution:

  • close the stale socket when an RPC request times out
  • reconnect based on the gateway client state
  • on prompt.submit timeout, query session.status; if the backend is running, treat the submit as accepted
  • rebind live session transports to the current WebSocket on session-scoped requests
  • add frontend and backend regression tests

Validation

  • npm --workspace apps/desktop run test:ui -- src/lib/json-rpc-gateway.test.ts
  • npm --workspace apps/desktop run type-check
  • scripts/run_tests.sh tests/test_tui_gateway_server.py -- -k session_lookup_rebinds_current_transport

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

After an idle/stale WebSocket, the desktop app should reconnect and keep the live session attached. If prompt.submit times out but the backend accepted the turn, the UI should continue waiting for the running turn instead of surfacing a fake failed prompt.

Still need to ship something?

×6

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

Back to top recommendations

TRENDING