NousResearch/hermes-agent

Matrix inbound sync handler awaiting and dispatch issue

Cluster 46142 · gateway. Data as of

Nothing open on GitHub. Fix merged in #56345 on 1 Jul 2026. Check it covers your case.

The short answer

0open issues
0open PRs
3items grouped
Known?
Yes. 3 related items grouped here, 1 issue already closed.
Fix event
A fix was merged to main in PR #56345. Check it covers your case. No release data is tracked.
Tracker
The maintainers' tracker marks this resolved, deciding PR #56345. That is separate from the fix event.
Still open
Nothing open on GitHub.

Two items share the title "fix(matrix): await inbound sync handlers", and a third is a bug report about inbound message dispatch on a Tuwunel homeserver after a mautrix migration (PR #18505). The titles suggest a shared Matrix inbound handling theme, but the available information does not confirm that the fixes address the reported bug.

Open issues0

No open issues.

Open PRs0

No open pull requests.

Fixes on record

Merged to main. A stamp counts the issues a fix is linked to.

  • #56345 fix(matrix): await inbound sync handlers

    merged to main

    files: plugins/platforms/matrix/adapter.py, scripts/release.py, tests/gateway/test_matrix.py

    Show the diff
    • plugins/platforms/matrix/adapter.py
      @@ -1459,9 +1459,21 @@ async def connect(self, *, is_reconnect: bool = False) -> bool:
               # Without this the INVITE handler below never fires.
               client.add_dispatcher(MembershipEventDispatcher)
       
      -        client.add_event_handler(EventType.ROOM_MESSAGE, self._on_room_message)
      -        client.add_event_handler(EventType.REACTION, self._on_reaction)
      -        client.add_event_handler(IntEvt.INVITE, self._on_invite)
      +        client.add_event_handler(
      +            EventType.ROOM_MESSAGE,
      +            self._on_room_message,
      +            wait_sync=True,
      +        )
      +        client.add_event_handler(
      +            EventType.REACTION,
      +            self._on_reaction,
      +            wait_sync=True,
      +        )
      +        client.add_event_handler(
      +            IntEvt.INVITE,
      +            self._on_invite,
      +            wait_sync=True,
      +        )
       
               # Initial sync to catch up, then start background sync.
               self._startup_ts = time.time()
    • scripts/release.py
      @@ -232,6 +232,7 @@
           "[email protected]": "synapsesx",
           "[email protected]": "itsflownium",
           "[email protected]": "dirtyren",
      +    "[email protected]": "yyzquwu",  # PR #47567 salvage (Matrix: register inbound handlers with wait_sync=True so _dispatch_sync's gather awaits them; without it mautrix fire-and-forgets and inbound intake has no completion point)
           "[redacted:email]": "tgmerritt",  # PR #43553 salvage (parse vLLM's token-based output-cap error format so over-cap max_tokens 400s reduce the output cap instead of death-looping into compression)
           "[email protected]": "justin-cyhuang",
           "[redacted:email]": "Tranquil-Flow",
    • tests/gateway/test_matrix.py
      @@ -106,7 +106,7 @@ def __init__(self, mxid=None, device_id=None, api=None,
                   self.crypto = None
                   self._event_handlers = {}
       
      -        def add_event_handler(self, event_type, handler):
      +        def add_event_handler(self, event_type, handler, **kwargs):
                   self._event_handlers.setdefault(event_type, []).append(handler)
       
               def add_dispatcher(self, dispatcher_type):
      @@ -2727,13 +2727,20 @@ async def test_connect_registers_encrypted_event_handler_when_encryption_on(self
                           with patch.object(adapter, "_sync_loop", AsyncMock(return_value=None)):
                               assert await adapter.connect() is True
       
      -        # Verify event handlers were registered.
      -        # In mautrix the order is: add_event_handler(EventType, callback)
      +        # Verify inbound event handlers were registered as sync-awaited
      +        # callbacks. mautrix only returns waited handler tasks from
      +        # handle_sync(), so background-only handlers leave _dispatch_sync()
      +        # without a completion point for Hermes' Matrix intake.
               handler_calls = mock_client.add_event_handler.call_args_list
      -        registered_types = [call.args[0] for call in handler_calls]
      +        waited_types = {
      +            str(call.args[0])
      +            for call in handler_calls
      +            if call.kwargs.get("wait_sync") is True
      +        }
       
      -        # Should have registered handlers for ROOM_MESSAGE, REACTION, INVITE
      -        assert len(handler_calls) >= 3
      +        assert "m.room.message" in waited_types
      +        assert "m.reaction" in waited_types
      +        assert "internal.invite" in waited_types
       
               await adapter.disconnect()
       

1 PR closed without merging

From the close comments: merged via another change 1

  • #47567 fix(matrix): await inbound sync handlers · merged via another change → 4c2c54c, #56345
Closed issues · 1
  • Closed#46142[Bug]: Matrix gateway — mautrix migration (PR #18505) breaks inbound message dispatch on Tuwunel homeserver
How this cluster was grouped
  • Link evidence (structural links throughout): every member is connected by structural evidence: shared changed files, or a closing/superseded reference.
  • Pairwise link density 0.67: the share of item 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.

Pick up a Lab task

Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.

Open the Lab

At a glance

Subsystem
gateway
Merged PRs
#56345
Closed issues
1
Attempts
1 PR closed without merging
Fix link checked
1 Jul 2026

For your agent

The same facts, typed.