hermes - 💡(How to fix) Fix Gateway unconditionally interrupts running agent during clarify, discarding user answer

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 the gateway agent is waiting for a clarify (text input from the user), and the user sends their answer, the Gateway treats the new message as an interrupt — killing the current turn and discarding the clarify response. The user sees ⚡ Interrupting current task instead of their answer being consumed, and the agent never receives the clarify input.

This is not a timeout issue — it happens even when the user replies instantly. The root cause is a message routing design flaw in the Gateway.

Root Cause

There are two separate message pathways in the Gateway:

Path A — Busy session handler (_handle_active_session_busy_message, gateway/run.py ~L2466):

  • Registered via adapter.set_busy_session_handler() and called by the adapter when the session has a running agent
  • Does NOT check for pending clarify. When busy_input_mode is "interrupt" (the default), it unconditionally calls running_agent.interrupt(event.text) (~L2555-2559) and sends the ⚡ Interrupting ack
  • Always returns True, consuming the message

Path B — Normal message handler (_handle_message, gateway/run.py ~L5651):

  • Does check for pending clarify (~L5831-5860) and correctly routes the reply
  • BUT is never reached when the session is busy — Path A intercepts first

The clarify check lives in _handle_message alongside the "session busy" guard (~L5966), but it gets shadowed because the adapter calls the dedicated busy handler instead of routing through _handle_message.

Key code references (commit v2026.5.7-559-g1979ef580):

WhatFileLine
Busy handler registrationgateway/run.py~L3478
Busy handler: interrupt (no clarify check)gateway/run.py~L2555-2559
Busy handler: ack with ⚡ Interruptinggateway/run.py~L2611-2614
Clarify detection (in _handle_message)gateway/run.py~L5837-5860
Session-busy guard (in _handle_message)gateway/run.py~L5966
AIAgent.interrupt()run_agent.py~L5178

Fix Action

Workaround

Despite the Gateway's official documentation (in hermes-agent skill SKILL.md) which acknowledges the clarify timeout issue and suggests increasing clarify_timeout as a mitigation — this does NOT fix the problem. The bug is structural, not timeout-related: even instant replies are discarded by the interrupt logic.

The only workaround is: after being interrupted, re-send your answer.

Code Example

# Before interrupting, check for pending clarify
from tools import clarify_gateway as _clarify_mod
_pending_clarify = _clarify_mod.get_pending_for_session(session_key)
if _pending_clarify is not None:
    _raw_clarify_reply = (event.text or "").strip()
    if _raw_clarify_reply and not _raw_clarify_reply.startswith("/"):
        _resolved = _clarify_mod.resolve_gateway_clarify(
            _pending_clarify.clarify_id, _raw_clarify_reply,
        )
        if _resolved:
            logger.info(
                "Clarify text response intercepted in busy handler (session=%s, id=%s)",
                session_key, _pending_clarify.clarify_id,
            )
            return True  # consume without interrupt
RAW_BUFFERClick to expand / collapse

Bug: Gateway unconditionally interrupts running agent during clarify, discarding user's answer

Description

When the gateway agent is waiting for a clarify (text input from the user), and the user sends their answer, the Gateway treats the new message as an interrupt — killing the current turn and discarding the clarify response. The user sees ⚡ Interrupting current task instead of their answer being consumed, and the agent never receives the clarify input.

This is not a timeout issue — it happens even when the user replies instantly. The root cause is a message routing design flaw in the Gateway.

Impact

Any messaging platform using the Gateway (Telegram, QQ Bot, Discord, etc.) that invokes the clarify tool is affected. The user's reply is silently dropped. The only workaround is to re-send the answer after the interrupt.

Steps to Reproduce

  1. Configure Hermes Gateway on any messaging platform (Telegram / QQ Bot / etc.)
  2. Send a message that triggers the agent to call clarify (e.g., a question with choices)
  3. The agent pauses, waiting for your text input
  4. Reply to the clarify question
  5. Actual: The gateway sends ⚡ Interrupting current task... — the clarify is cancelled, your answer is lost
  6. Expected: The reply should be routed to the pending clarify and the agent should continue

Root Cause

There are two separate message pathways in the Gateway:

Path A — Busy session handler (_handle_active_session_busy_message, gateway/run.py ~L2466):

  • Registered via adapter.set_busy_session_handler() and called by the adapter when the session has a running agent
  • Does NOT check for pending clarify. When busy_input_mode is "interrupt" (the default), it unconditionally calls running_agent.interrupt(event.text) (~L2555-2559) and sends the ⚡ Interrupting ack
  • Always returns True, consuming the message

Path B — Normal message handler (_handle_message, gateway/run.py ~L5651):

  • Does check for pending clarify (~L5831-5860) and correctly routes the reply
  • BUT is never reached when the session is busy — Path A intercepts first

The clarify check lives in _handle_message alongside the "session busy" guard (~L5966), but it gets shadowed because the adapter calls the dedicated busy handler instead of routing through _handle_message.

Key code references (commit v2026.5.7-559-g1979ef580):

WhatFileLine
Busy handler registrationgateway/run.py~L3478
Busy handler: interrupt (no clarify check)gateway/run.py~L2555-2559
Busy handler: ack with ⚡ Interruptinggateway/run.py~L2611-2614
Clarify detection (in _handle_message)gateway/run.py~L5837-5860
Session-busy guard (in _handle_message)gateway/run.py~L5966
AIAgent.interrupt()run_agent.py~L5178

Suggested Fix

In _handle_active_session_busy_message, before the interrupt logic at ~L2555, add a pending-clarify check similar to the one in _handle_message (~L5837-5860):

# Before interrupting, check for pending clarify
from tools import clarify_gateway as _clarify_mod
_pending_clarify = _clarify_mod.get_pending_for_session(session_key)
if _pending_clarify is not None:
    _raw_clarify_reply = (event.text or "").strip()
    if _raw_clarify_reply and not _raw_clarify_reply.startswith("/"):
        _resolved = _clarify_mod.resolve_gateway_clarify(
            _pending_clarify.clarify_id, _raw_clarify_reply,
        )
        if _resolved:
            logger.info(
                "Clarify text response intercepted in busy handler (session=%s, id=%s)",
                session_key, _pending_clarify.clarify_id,
            )
            return True  # consume without interrupt

Alternatively, the adapter could route all messages through _handle_message even for busy sessions, but that's a larger refactor.

Environment

  • Hermes Agent version: v2026.5.7-559-g1979ef580 (recent main)
  • Platforms affected: all Gateway-based messaging platforms (Telegram, QQ Bot, Discord, etc.)
  • busy_input_mode: "interrupt" (default)

Workaround

Despite the Gateway's official documentation (in hermes-agent skill SKILL.md) which acknowledges the clarify timeout issue and suggests increasing clarify_timeout as a mitigation — this does NOT fix the problem. The bug is structural, not timeout-related: even instant replies are discarded by the interrupt logic.

The only workaround is: after being interrupted, re-send your answer.

Note

The TUI (ui-tui/ + tui_gateway/) does not have this bug. It defaults to busy_input_mode: "queue" (not "interrupt"), has a dedicated clarify.respond JSON-RPC method that routes answers without interrupting, and its session.interrupt explicitly avoids canceling active clarify/sudo/secret prompts.

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