Skip to content

fix(cli): await run_in_terminal futures to prevent RuntimeWarning - #26617

Closed
laychiman wants to merge 1 commit into
NousResearch:mainfrom
laychiman:fix/run-in-terminal-coroutine-wait
Closed

laychiman wants to merge 1 commit into
NousResearch:mainfrom
laychiman:fix/run-in-terminal-coroutine-wait

Conversation

@laychiman

Copy link
Copy Markdown

Problem

prompt_toolkit.application.run_in_terminal() returns an Awaitable[_T] (an asyncio.Future) since prompt_toolkit 3.0+. Hermes discards the return value at two call sites, triggering:

RuntimeWarning: coroutine 'run_in_terminal.<locals>.run' was never awaited

Affects /new, /reset, /undo slash commands dispatched from the process_loop daemon thread.

Fix

Capture the returned Future and block until completion via threading.Event + add_done_callback, with a 60s timeout.

Changed

  • _run_curses_picker() — block on _pick() future
  • _prompt_text_input() — block on _ask() future

Why not asyncio.ensure_future()?

These call sites depend on result[0] being set before returning, so fire-and-forget is insufficient. The threading.Event pattern ensures the scheduled coroutine completes before we read the result.

Related

prompt_toolkit 3.0+ changed run_in_terminal() to return an
Awaitable[_T] (asyncio.Future). Hermes discarded it at two call
sites, causing RuntimeWarning on /new, /reset, /undo confirmation.

Capture the returned Future and block until completion via
threading.Event + add_done_callback, with a 60s timeout.

Closes NousResearch#23297, closes NousResearch#22970

Co-authored-by: Bartok9 <...@...>
@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 15, 2026
@alt-glitch

Copy link
Copy Markdown
Contributor

Related: Fixes #22970 and #23297. Competing fix PRs for the same root cause: #22851, #22972, #22987, #23210, #23317. Also complements #23302 (mentioned in body).

@teknium1

Copy link
Copy Markdown
Collaborator

This looks implemented on current main via the merged alternate fix path.

Evidence from this automated hermes-sweeper review:

  • c5f1f863acd49c92d9fbe92550115d51dd5181d0 / fix(cli): drive _prompt_text_input directly when off main thread (#23185) #23454 fixed the slash-command process_loop daemon-thread path by bypassing run_in_terminal off the main prompt_toolkit thread.
  • Current cli.py:6287 documents that run_in_terminal returns a coroutine driven by the main-thread event loop, and cli.py:6306 only calls it when self._app exists and the current thread is the main thread; daemon-thread slash commands fall back to direct input().
  • Current cli.py:6257 applies the same main-thread guard to _run_curses_picker, so the process_loop background-thread path calls _pick() directly instead of orphaning a coroutine.
  • The related fix: 4 small surgical bugs — kanban delete alias, gateway title noise, bg truncation, cprint coroutine #23302 complement mentioned in this PR was also salvaged in 365da2d2dfd92bd16f1993c8fefea05508282db8, which schedules the fire-and-forget _cprint run_in_terminal coroutine via asyncio.ensure_future.

Thanks for the PR and the clear analysis. The specific warning path it targeted has been resolved on main by the merged fixes above.

@teknium1 teknium1 closed this Jun 12, 2026
@teknium1 teknium1 added the sweeper:implemented-on-main Sweeper: behavior already present on current main label Jun 12, 2026
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 sweeper:implemented-on-main Sweeper: behavior already present on current main type/bug Something isn't working

Projects

None yet

3 participants