Summary
In production with OpenClaw + @tencent-weixin/openclaw-weixin, nearly every inbound user text message is processed twice (~1 second apart). Transcripts show dup≈2 for the same user content; agents answer twice / burn double tool calls.
Environment
- Plugin:
@tencent-weixin/openclaw-weixin@2.4.6
- Host: OpenClaw gateway (private banking mid-office deploy)
- Channel:
openclaw-weixin personal WeChat (iLink getUpdates long-poll)
Evidence (redacted)
- Staff agent WeChat session over ~10h wall time: ~26 unique user texts, ~52 raw user turns (almost every message duplicated).
- Pair spacing typically ~1s, same body text.
- Not explained by user double-tap; pattern is systematic across the session.
Root cause (code)
monitorWeixinProvider loops resp.msgs and calls processOneMessage with no dedupe (src/monitor/monitor.ts).
processOneMessage has no claim/dedupe before slash-command / media / dispatchReplyFromConfig (src/messaging/process-message.ts).
- Wire messages expose
message_id / seq / client_id (logged in debug), but weixinMessageToMsgContext stamps a fresh random MessageSid via generateId("openclaw-weixin") every delivery (src/messaging/inbound.ts) — so downstream cannot correlate replays either.
Sibling OpenClaw channels (Telegram / Slack / WhatsApp) already use replay guards / durable event ids for at-least-once transports. Weixin does not.
Expected
A logical WeChat message (same message_id, or stable fallback) should run the inbound AI pipeline once within a short TTL window.
Proposed fix
See accompanying PR: short-TTL in-memory claim in processOneMessage keyed by message_id → client_id → seq → body fingerprint; stable MessageSid from the same key.
Workaround (operators)
Session-level “answer once if user text repeats” in agent SOUL — does not stop double tool spend.
Summary
In production with OpenClaw +
@tencent-weixin/openclaw-weixin, nearly every inbound user text message is processed twice (~1 second apart). Transcripts showdup≈2for the same user content; agents answer twice / burn double tool calls.Environment
@tencent-weixin/openclaw-weixin@2.4.6openclaw-weixinpersonal WeChat (iLinkgetUpdateslong-poll)Evidence (redacted)
Root cause (code)
monitorWeixinProviderloopsresp.msgsand callsprocessOneMessagewith no dedupe (src/monitor/monitor.ts).processOneMessagehas no claim/dedupe before slash-command / media /dispatchReplyFromConfig(src/messaging/process-message.ts).message_id/seq/client_id(logged in debug), butweixinMessageToMsgContextstamps a fresh randomMessageSidviagenerateId("openclaw-weixin")every delivery (src/messaging/inbound.ts) — so downstream cannot correlate replays either.Sibling OpenClaw channels (Telegram / Slack / WhatsApp) already use replay guards / durable event ids for at-least-once transports. Weixin does not.
Expected
A logical WeChat message (same
message_id, or stable fallback) should run the inbound AI pipeline once within a short TTL window.Proposed fix
See accompanying PR: short-TTL in-memory claim in
processOneMessagekeyed bymessage_id→client_id→seq→ body fingerprint; stableMessageSidfrom the same key.Workaround (operators)
Session-level “answer once if user text repeats” in agent SOUL — does not stop double tool spend.