# NousResearch/hermes-agent · TUI freeze caused by blocking completion RPCs

## Open now

- Nothing open on GitHub.

A bug where typing '@' in the TUI triggers a completion RPC that blocks the stdio pipe and freezes the interface. The fixes route or skip these RPCs to prevent the freeze.

## TL;DR

- 3 member(s): 0 open issue(s), 1 closed issue(s), 0 open PR(s), 1 merged PR(s), 1 PR(s) closed without merging.
- A fix was merged to main in PR #53895. Verify it addresses your case.
- **Recommended:** read PR #53895 (and any competing PRs below) before filing. Confirm the merged change covers your symptom.

## Maintainer resolution verdict

- Internal-tracker verdict over this cluster's issue members: `resolved` · deciding PR(s): `pr-53895`. This is distinct from the fix status above. Weigh it yourself.

## How this cluster was grouped

- Link evidence (`STRUCTURAL_SPANNING`): every member is connected by structural evidence: shared changed files, or a closing/superseded reference.
- Pairwise link density `0.67`: the share of member pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. `1.00` means every pair is linked.

## Closed / duplicate issues

- #21123: TUI freezes when typing @ character — complete.path RPC timeout blocks stdio pipe

## Prior & competing PRs

- **#53895: fix(tui): route completion RPCs to the pool so they can't freeze the TUI**. merged to main · fix tier `verified`
  - maintainer direction: category `merged`
  - files: `tests/tui_gateway/test_protocol.py`, `tui_gateway/server.py`
  - fix hunks:
  - `tests/tui_gateway/test_protocol.py`

    ```diff
    @@ -1736,3 +1736,37 @@ def test_dispatch_unknown_long_method_still_goes_inline(server):
         resp = server.dispatch({"id": "r4", "method": "some.method", "params": {}})
     
         assert resp["result"] == {"ok": True}
    +
    +
    [redacted:email]("completion_method", ["complete.path", "complete.slash"])
    +def test_completion_handlers_are_pool_routed(completion_method, server):
    +    """complete.path/complete.slash must run on the pool, never the reader thread.
    +
    +    Regression for #21123: completion ran inline, so a slow git ls-files /
    +    skill-scan blocked prompt.submit and froze the TUI for the 120s RPC timeout.
    +    """
    +    assert completion_method in server._LONG_HANDLERS
    +
    +
    [redacted:email]("completion_method", ["complete.path", "complete.slash"])
    +def test_slow_completion_does_not_block_fast_handler(completion_method, server):
    +    """A slow completion RPC must not block a concurrent fast handler (#21123)."""
    +    released = threading.Event()
    +
    +    def slow_completion(rid, params):
    +        released.wait(timeout=5)
    +        return server._ok(rid, {"items": []})
    +
    +    server._methods[completion_method] = slow_completion
    +    server._methods["fast.ping"] = lambda rid, params: server._ok(rid, {"pong": True})
    +
    +    t0 = time.monotonic()
    +    assert server.dispatch({"id": "slow", "method": completion_method, "params": {}}) is None
    +
    +    fast_resp = server.dispatch({"id": "fast", "method": "fast.ping", "params": {}})
    +    fast_elapsed = time.monotonic() - t0
    +
    +    assert fast_resp["result"] == {"pong": True}
    +    assert fast_elapsed < 0.5, f"fast handler blocked for {fast_elapsed:.2f}s behind {completion_method}"
    +
    +    released.set()
    ```
  - `tui_gateway/server.py`

    ```diff
    @@ -178,6 +178,16 @@ def _thread_panic_hook(args):
             "billing.step_up",
             "browser.manage",
             "cli.exec",
    +        # Completion RPCs run inline on the reader thread by default, but both
    +        # can block it for seconds: complete.path spawns `git ls-files` and
    +        # fuzzy-ranks the whole repo (slow on large repos / WSL2 mounts), and
    +        # complete.slash does first-call prompt_toolkit imports + a skill-dir
    +        # scan. While either runs inline, prompt.submit / session.interrupt sit
    +        # unread in the stdin pipe — the TUI appears frozen until the 120s RPC
    +        # timeout fires (#21123). Routing them to the pool keeps the fast path
    +        # responsive; completion is read-only and write_json is lock-guarded.
    +        "complete.path",
    +        "complete.slash",
             "llm.oneshot",
             # Pet RPCs hit the network (manifest fetch / spritesheet download) or do
             # per-frame PNG decode/encode (pet.cells): inline they serialize on the
    ```
- **#21142: fix: skip bare @ completion RPC in TUI**. closed without merge
  - maintainer direction: category `implemented_elsewhere`; implication `superseded`; refs `#21123`, `#53895`

## Fix status

- Merged to main in PR #53895 (cited above). No release data is tracked. Verify downstream.
- Fix last verified (merged) `2026-06-28`.
- Subsystem: `hermes_cli`
