Skip to content

Bug: busy_input_mode: queue silently drops messages — single-slot overwrite instead of FIFO #28503

@huoxiaojun2009

Description

@huoxiaojun2009

Summary
When busy_input_mode: queue is configured, Hermes is supposed to queue incoming messages while the agent is busy. However, the implementation uses a single-slot dictionary (_pending_messages[session_key]) that overwrites previous messages rather than appending them to a FIFO queue. This causes silent message loss when users send multiple messages rapidly while the agent is processing.
Environment
Hermes Agent version: latest (installed from NousResearch/hermes-agent.git)
Platform: WeChat (Weixin) gateway, also affects all platforms
Config: display.busy_input_mode: queue
Steps to Reproduce
Configure busy_input_mode: queue in config.yaml
Send a message to the agent (triggers a long-running task)
While the agent is busy, send messages 2, 3, 4, 5 rapidly
Wait for the agent to finish the current task
Result: The agent only processes the last message (message 5). Messages 2, 3, 4 are silently lost.
Root Cause Analysis
The single-slot design
In gateway/platforms/base.py:1092:
def merge_pending_message_event(
pending_messages: Dict[str, MessageEvent],
session_key: str,
event: MessageEvent,
*,
merge_text: bool = False,
) -> None:
# ... photo burst and media merge logic ...

# Plain TEXT messages with merge_text=False: REPLACE, not append
pending_messages[session_key] = event  # ← OVERWRITES previous

The pending_messages dict is keyed by session_key — it holds one event per session, not a list.
Queue mode path doesn't enable text merging
In gateway/run.py:5210-5212:
if self._busy_input_mode == "queue":
logger.debug("PRIORITY queue follow-up for session %s", _quick_key)
self._queue_or_replace_pending_event(_quick_key, event) # ← calls merge WITHOUT merge_text
return None
_queue_or_replace_pending_event calls merge_pending_message_event with the default merge_text=False, so plain text messages are replaced, not appended.
Inconsistent: one path DOES merge text
In gateway/run.py:5175-5180 (agent-starting sentinel path):
merge_pending_message_event(
adapter._pending_messages,
_quick_key,
event,
merge_text=True, # ← Only this path enables text merging
)
This inconsistency suggests the single-slot design was intended for photo bursts only, and queue mode was later layered on top without converting to a true FIFO.
Expected Behavior
All queued messages should be preserved and processed sequentially (FIFO) after the agent finishes the current task.
Suggested Fix
Two possible approaches:
Option A: Enable merge_text=True for queue mode (quick fix)
In gateway/run.py:5210-5212, pass merge_text=True:
if self._busy_input_mode == "queue":
merge_pending_message_event(
adapter._pending_messages, _quick_key, event, merge_text=True
)
return None
This would concatenate text messages with newlines, so they're all processed in one turn. Not perfect FIFO (they become one combined message), but at least no data loss.
Option B: Convert to real FIFO queue (proper fix)
Change _pending_messages from Dict[str, MessageEvent] to Dict[str, List[MessageEvent]] (or collections.deque), and process them one by one after the agent finishes. This preserves message boundaries and enables true sequential processing.
Workaround
Users can mitigate by:
Sending all content in a single message (newline-separated)
Waiting for the agent to respond before sending the next message
For link collection workflows: writing links to a file and processing them in batch

Impact
This is particularly painful for messaging platforms (WeChat, Telegram) where rapid-fire message sending is normal user behavior. Users have no indication that messages were lost — no warning, no error, just silent data disappearance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High — major feature broken, no workaroundcomp/gatewayGateway runner, session dispatch, deliverytype/bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions