Skip to content

[Bug] getUpdates at-least-once delivery double-invokes AI pipeline (≈1s duplicate user messages) #239

Description

@ericcaiwx-star

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)

  1. monitorWeixinProvider loops resp.msgs and calls processOneMessage with no dedupe (src/monitor/monitor.ts).
  2. processOneMessage has no claim/dedupe before slash-command / media / dispatchReplyFromConfig (src/messaging/process-message.ts).
  3. 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_idclient_idseq → 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions