hermes - 💡(How to fix) Fix WeChat adapter content dedup silently drops repeated commands, breaking /approve workflow [2 pull requests]

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…

Error Message

Gateway log shows inbound messages received but not processed:

2026-05-21 10:38:36,813 INFO gateway.platforms.weixin: [Weixin] inbound from=o9cq80yM type=dm media=0
2026-05-21 10:38:57,088 INFO gateway.platforms.weixin: [Weixin] inbound from=o9cq80yM type=dm media=0
2026-05-21 10:40:54,949 INFO gateway.platforms.weixin: [Weixin] inbound from=o9cq80yM type=dm media=0
2026-05-21 10:40:54,949 INFO gateway.run: inbound message: ... msg='Are you back?'
2026-05-21 10:41:22,074 INFO gateway.platforms.weixin: [Weixin] inbound from=o9cq80yM type=dm media=0
2026-05-21 10:41:41,302 INFO gateway.platforms.weixin: [Weixin] inbound from=o9cq80yM type=dm media=0

Note: Many inbound from= entries have no corresponding inbound message: entry — those were silently dropped by content dedup. In one day, 2074 inbound messages were received but only 1226 were processed (848 silently dropped, ~41% drop rate).

Root Cause

This is the more critical issue. When an agent session has multiple tool calls requiring approval, the /approve command must be sent once per pending approval. However, because content dedup treats repeated /approve as duplicate messages:

Fix Action

Fixed

Code Example

# Layer 1: message_id dedup (reasonable - prevents network retry duplicates)
message_id = str(message.get("message_id") or "").strip()
if message_id and self._dedup.is_duplicate(message_id):
    return

# Layer 2: content fingerprint dedup (problematic)
text = _extract_text(item_list)
if text:
    content_key = f"content:{sender_id}:{hashlib.md5(text.encode()).hexdigest()}"
    if self._dedup.is_duplicate(content_key):
        logger.debug("[%s] Content-dedup: skipping duplicate message from %s", self.name, sender_id)
        return  # ← silently dropped, only DEBUG log

---

class MessageDeduplicator:
    """TTL-based message deduplication cache.

    Replaces the identical `_seen_messages` / `_is_duplicate()` pattern
    previously duplicated in discord, slack, dingtalk, wecom, weixin,
    mattermost, and feishu adapters.
    """

    def __init__(self, max_size: int = 2000, ttl_seconds: float = 300):
        # ...

---

logger.warning("[%s] Content-dedup: dropping repeated message from %s: %s", self.name, _safe_id(sender_id), text[:50])

---

if not text.startswith("/"):
    content_key = f"content:{sender_id}:{hashlib.md5(text.encode()).hexdigest()}"
    if self._dedup.is_duplicate(content_key):
        return

---

2026-05-21 10:38:36,813 INFO gateway.platforms.weixin: [Weixin] inbound from=o9cq80yM type=dm media=0
2026-05-21 10:38:57,088 INFO gateway.platforms.weixin: [Weixin] inbound from=o9cq80yM type=dm media=0
2026-05-21 10:40:54,949 INFO gateway.platforms.weixin: [Weixin] inbound from=o9cq80yM type=dm media=0
2026-05-21 10:40:54,949 INFO gateway.run: inbound message: ... msg='Are you back?'
2026-05-21 10:41:22,074 INFO gateway.platforms.weixin: [Weixin] inbound from=o9cq80yM type=dm media=0
2026-05-21 10:41:41,302 INFO gateway.platforms.weixin: [Weixin] inbound from=o9cq80yM type=dm media=0
RAW_BUFFERClick to expand / collapse

WeChat adapter content dedup silently drops repeated commands, breaking /approve workflow

Environment

  • Hermes Agent: v2026.5.16-594-g0ba7339f7
  • Platform: WeChat (iLink Bot adapter)
  • Files: gateway/platforms/weixin.py, gateway/platforms/helpers.py

Problem

The WeChat adapter has a content fingerprint dedup mechanism that silently discards messages with identical text from the same sender within a 5-minute TTL window, even when the user intentionally sends the same command multiple times.

Code location

gateway/platforms/weixin.py_process_message() (line 1379):

# Layer 1: message_id dedup (reasonable - prevents network retry duplicates)
message_id = str(message.get("message_id") or "").strip()
if message_id and self._dedup.is_duplicate(message_id):
    return

# Layer 2: content fingerprint dedup (problematic)
text = _extract_text(item_list)
if text:
    content_key = f"content:{sender_id}:{hashlib.md5(text.encode()).hexdigest()}"
    if self._dedup.is_duplicate(content_key):
        logger.debug("[%s] Content-dedup: skipping duplicate message from %s", self.name, sender_id)
        return  # ← silently dropped, only DEBUG log

gateway/platforms/helpers.pyMessageDeduplicator (line 27):

class MessageDeduplicator:
    """TTL-based message deduplication cache.

    Replaces the identical `_seen_messages` / `_is_duplicate()` pattern
    previously duplicated in discord, slack, dingtalk, wecom, weixin,
    mattermost, and feishu adapters.
    """

    def __init__(self, max_size: int = 2000, ttl_seconds: float = 300):
        # ...

TTL is set to MESSAGE_DEDUP_TTL_SECONDS = 300 (5 minutes) in weixin.py line 96.

Impact 1: Repeated commands are silently ignored

When a user sends the same command multiple times (e.g., /restart-sglang to restart a service that failed), only the first one is processed. All subsequent identical messages within the 5-minute TTL are silently discarded by the content dedup cache.

Observed behavior: User sent /restart-sglang many times via WeChat. Only the first message was processed (or lost during gateway restart). All subsequent attempts were silently dropped. The gateway logs show inbound from= entries but no inbound message: entries — the messages were discarded before reaching the command handler.

Impact 2: /approve workflow breaks when multiple dangerous commands need approval

This is the more critical issue. When an agent session has multiple tool calls requiring approval, the /approve command must be sent once per pending approval. However, because content dedup treats repeated /approve as duplicate messages:

  1. First /approve → processed, approves the first pending command
  2. Second /approvesilently dropped by content dedup (same text, same sender, within 5-min TTL)
  3. Third /approvesilently dropped (same reason)
  4. ... and so on

Result: Only the first approval succeeds. The user has no way to approve subsequent commands because sending /approve again is treated as a duplicate. The user must work around this by sending different text each time (e.g., alternating between /approve, /approve session, /approve always) or waiting 5 minutes for the TTL to expire.

Why this happens

The content dedup uses content:{sender_id}:{md5(text)} as the key. Since /approve is always the same text from the same sender, it gets cached after the first use and all subsequent attempts within 5 minutes are silently discarded.

The discard is logged at DEBUG level only, so users running at INFO level have no visibility into why their messages are being ignored.

Affected platforms

The MessageDeduplicator helper is shared across discord, slack, dingtalk, wecom, weixin, mattermost, and feishu adapters. However, only weixin.py implements the content fingerprint dedup layer (line 1391-1398). Other adapters only use message_id dedup. This makes WeChat uniquely affected.

Suggested fix

Option A (recommended): Remove the content fingerprint dedup from weixin.py entirely. The message_id dedup already handles the original problem (network retries causing duplicate deliveries). Content dedup is over-aggressive and causes real user-facing issues.

Option B: At minimum, change the discard log from DEBUG to WARNING so users can see when messages are dropped:

logger.warning("[%s] Content-dedup: dropping repeated message from %s: %s", self.name, _safe_id(sender_id), text[:50])

Option C: Exclude slash commands from content dedup:

if not text.startswith("/"):
    content_key = f"content:{sender_id}:{hashlib.md5(text.encode()).hexdigest()}"
    if self._dedup.is_duplicate(content_key):
        return

Reproduction

  1. Connect Hermes gateway to WeChat via iLink Bot
  2. Send any slash command (e.g., /help)
  3. Immediately send the same command again (within 5 minutes)
  4. Observe: second command is silently dropped (check gateway.log — you'll see inbound from= but no inbound message:)

Logs

Gateway log shows inbound messages received but not processed:

2026-05-21 10:38:36,813 INFO gateway.platforms.weixin: [Weixin] inbound from=o9cq80yM type=dm media=0
2026-05-21 10:38:57,088 INFO gateway.platforms.weixin: [Weixin] inbound from=o9cq80yM type=dm media=0
2026-05-21 10:40:54,949 INFO gateway.platforms.weixin: [Weixin] inbound from=o9cq80yM type=dm media=0
2026-05-21 10:40:54,949 INFO gateway.run: inbound message: ... msg='Are you back?'
2026-05-21 10:41:22,074 INFO gateway.platforms.weixin: [Weixin] inbound from=o9cq80yM type=dm media=0
2026-05-21 10:41:41,302 INFO gateway.platforms.weixin: [Weixin] inbound from=o9cq80yM type=dm media=0

Note: Many inbound from= entries have no corresponding inbound message: entry — those were silently dropped by content dedup. In one day, 2074 inbound messages were received but only 1226 were processed (848 silently dropped, ~41% drop rate).

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

hermes - 💡(How to fix) Fix WeChat adapter content dedup silently drops repeated commands, breaking /approve workflow [2 pull requests]