# NousResearch/hermes-agent · Matrix multi-bot infinite reply loop issue

## Open now

- Nothing open on GitHub.

A bug where MATRIX_AUTO_THREAD causes infinite reply loops when multiple bots share a Matrix room, along with a proposed fix using a thread_require_mention option to prevent this behavior.

## 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 #28580. Verify it addresses your case.
- **Recommended:** read PR #28580 (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-28580`. 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

- #27995: bug: MATRIX_AUTO_THREAD enables infinite reply loops when multiple bots share a Matrix room

## Prior & competing PRs

- **#28580: fix(matrix): implement thread_require_mention to prevent multi-agent reply loops (#27996)**. merged to main · fix tier `verified`
  - maintainer direction: category `merged`
  - files: `gateway/platforms/matrix.py`
  - fix hunks:
  - `gateway/platforms/matrix.py`

    ```diff
    @@ -380,6 +380,7 @@ def __init__(self, config: PlatformConfig):
             self._require_mention: bool = os.getenv(
                 "MATRIX_REQUIRE_MENTION", "true"
             ).lower() not in {"false", "0", "no"}
    +        self._thread_require_mention: bool = self._parse_thread_require_mention(config)
             free_rooms_raw = config.extra.get("free_response_rooms")
             if free_rooms_raw is None:
                 free_rooms_raw = os.getenv("MATRIX_FREE_RESPONSE_ROOMS", "")
    ```

    ```diff
    @@ -468,6 +469,27 @@ def _is_duplicate_event(self, event_id) -> bool:
             self._processed_events_set.add(event_id)
             return False
     
    +    @staticmethod
    +    def _parse_thread_require_mention(config) -> bool:
    +        """Parse thread_require_mention from config.extra or env var.
    +
    +        Handles both YAML booleans and string values (``\"true\"``, ``\"false\"``,
    +        ``\"yes\"``, ``\"no\"``, ``\"on\"``, ``\"off\"``, ``\"1\"``, ``\"0\"``).
    +        Falls back to ``MATRIX_THREAD_REQUIRE_MENTION`` env var, default ``false``.
    +        Mirrors Discord adapter's parsing pattern.
    +        """
    +        configured = config.extra.get("thread_require_mention")
    +        if configured is not None:
    +            if isinstance(configured, bool):
    +                return configured
    +            if isinstance(configured, str):
    +                return configured.lower() not in {"false", "0", "no", "off"}
    +            # int, float, etc. — truthiness fallback
    +            return bool(configured)
    +        return os.getenv(
    +            "MATRIX_THREAD_REQUIRE_MENTION", "false"
    +        ).lower() in {"true", "1", "yes", "on"}
    +
         # ------------------------------------------------------------------
         # E2EE helpers
         # ------------------------------------------------------------------
    ```

    ```diff
    @@ -1701,6 +1723,21 @@ async def _resolve_message_context(
                         )
                         return None
     
    +            # Thread-level @mention gating: even in a bot-participated thread,
    +            # require @mention when thread_require_mention is enabled.
    +            # Prevents infinite reply loops in multi-agent shared rooms
    +            # where multiple bots all participate in the same thread.
    +            elif (self._thread_require_mention and in_bot_thread
    +                  and not is_free_room):
    +                if not is_mentioned:
    +                    logger.debug(
    +                        "Matrix: ignoring message %s in thread %s — "
    +                        "no @mention (thread_require_mention=true)",
    +                        event_id,
    +                        thread_id,
    +                    )
    +                    return None
    +
             # DM mention-thread.
             if is_dm and not thread_id and self._dm_mention_threads and is_mentioned:
                 thread_id = event_id
    ```
- **#27996: fix(matrix): implement thread_require_mention to prevent multi-agent reply loops**. closed without merge
  - maintainer direction: category `merged_via`; implication `superseded`; refs `276e6cc52d4a8e0a6818bc3ba82a947013fb757c`, `#28580`

## Fix status

- Merged to main in PR #28580 (cited above). No release data is tracked. Verify downstream.
- Fix last verified (merged) `2026-05-19`.
