openclaw - 💡(How to fix) Fix [openclaw-weixin] Messages are delivered hundreds of times causing API rate limiting [1 participants]

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…
GitHub stats
openclaw/openclaw#56902Fetched 2026-04-08 01:46:18
View on GitHub
Comments
0
Participants
1
Timeline
0
Reactions
0
Author
Participants

Root Cause

Looking at the plugin source code:

  • src/monitor/monitor.ts: The monitorWeixinProvider long-poll loop calls processOneMessage() for every item returned by getUpdates(), with no deduplication based on message_id, seq, or any other unique identifier.
  • src/messaging/inbound.ts: weixinMessageToMsgContext() generates a new random MessageSid (via generateId()) for each call, so even duplicate messages from the API get unique internal IDs.

When the Weixin getUpdates API returns the same message multiple times (possibly due to network retries, long-poll overlap, or API-side duplication), every copy is treated as a brand new message.

Fix Action

Fix / Workaround

We have applied this patch locally and it resolves the issue.

Code Example

const recentMessageKeys = new Map<string, number>();
const DEDUP_TTL_MS = 120_000;

function dedupKey(msg) {
  if (msg.message_id) return \mid:\\;
  if (msg.seq) return \seq:\:\\;
  return \	s:\:\\;
}

function isDuplicate(msg) {
  // periodic cleanup of expired entries ...
  const key = dedupKey(msg);
  if (recentMessageKeys.has(key)) return true;
  recentMessageKeys.set(key, Date.now());
  return false;
}

---

if (isDuplicate(full)) {
  aLog.debug(\Skipping duplicate message: \\);
  continue;
}
RAW_BUFFERClick to expand / collapse

Bug Description

The @tencent-weixin/openclaw-weixin plugin (v2.1.1) delivers the same inbound message hundreds of times to the OpenClaw agent pipeline, rapidly exhausting API rate limits on the upstream LLM provider.

Environment

  • OpenClaw: 2026.3.28 (stable)
  • Plugin: @tencent-weixin/[email protected]
  • OS: Windows 11 Enterprise LTSC (Build 26100)
  • Node: v25.2.1

Steps to Reproduce

  1. Send a single text message via WeChat to the bot
  2. Observe the agent session — the same message (identical message_id and imestamp) is processed 100+ times
  3. The upstream LLM API (e.g. Kimi) quickly hits rate limits (429)

Expected Behavior

Each unique message should be processed exactly once.

Actual Behavior

A single message is delivered and processed hundreds of times in rapid succession. The conversation history shows the same message_id repeated 200+ times.

Root Cause Analysis

Looking at the plugin source code:

  • src/monitor/monitor.ts: The monitorWeixinProvider long-poll loop calls processOneMessage() for every item returned by getUpdates(), with no deduplication based on message_id, seq, or any other unique identifier.
  • src/messaging/inbound.ts: weixinMessageToMsgContext() generates a new random MessageSid (via generateId()) for each call, so even duplicate messages from the API get unique internal IDs.

When the Weixin getUpdates API returns the same message multiple times (possibly due to network retries, long-poll overlap, or API-side duplication), every copy is treated as a brand new message.

Suggested Fix

Add an in-memory deduplication cache in monitor.ts before calling processOneMessage():

const recentMessageKeys = new Map<string, number>();
const DEDUP_TTL_MS = 120_000;

function dedupKey(msg) {
  if (msg.message_id) return \mid:\\;
  if (msg.seq) return \seq:\:\\;
  return \	s:\:\\;
}

function isDuplicate(msg) {
  // periodic cleanup of expired entries ...
  const key = dedupKey(msg);
  if (recentMessageKeys.has(key)) return true;
  recentMessageKeys.set(key, Date.now());
  return false;
}

Then in the message loop:

if (isDuplicate(full)) {
  aLog.debug(\Skipping duplicate message: \\);
  continue;
}

We have applied this patch locally and it resolves the issue.

Labels

bug, openclaw-weixin

extent analysis

Fix Plan

To fix the issue of duplicate message processing, follow these steps:

  • Add an in-memory deduplication cache in monitor.ts to store recently processed message keys.
  • Implement a dedupKey function to generate a unique key for each message based on its message_id, seq, or other unique identifier.
  • Create an isDuplicate function to check if a message has been processed recently.
  • Use the isDuplicate function to skip duplicate messages in the message loop.

Example Code

// Add an in-memory deduplication cache
const recentMessageKeys = new Map<string, number>();
const DEDUP_TTL_MS = 120_000; // 2 minutes

// Generate a unique key for each message
function dedupKey(msg) {
  if (msg.message_id) return `mid:${msg.message_id}`;
  if (msg.seq) return `seq:${msg.seq}`;
  return `sid:${msg.sid}`;
}

// Check if a message has been processed recently
function isDuplicate(msg) {
  const key = dedupKey(msg);
  if (recentMessageKeys.has(key)) {
    const timestamp = recentMessageKeys.get(key);
    if (Date.now() - timestamp < DEDUP_TTL_MS) {
      return true;
    }
  }
  recentMessageKeys.set(key, Date.now());
  return false;
}

// Skip duplicate messages in the message loop
if (isDuplicate(full)) {
  aLog.debug(`Skipping duplicate message: ${dedupKey(full)}`);
  continue;
}

Verification

To verify that the fix worked, send a single text message via WeChat to the bot and observe the agent session. The same message should not be processed multiple times, and the conversation history should not show duplicate message IDs.

Extra Tips

  • Make sure to periodically clean up expired entries from the recentMessageKeys cache to prevent memory leaks.
  • Consider using a more robust deduplication mechanism, such as a distributed cache or a database, if the in-memory cache is not sufficient for your use case.
  • Monitor the agent session and conversation history to ensure that the fix does not introduce any new issues or side effects.

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