openclaw - 💡(How to fix) Fix Message Duplication in QQBot Channel

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…

I am experiencing frequent message duplication in the QQBot channel. Multiple issues contribute to this problem:

Root Cause

I am experiencing frequent message duplication in the QQBot channel. Multiple issues contribute to this problem:

Fix Action

Fix / Workaround

1. Heartbeat Session Message Leakage

  • Symptom: Heartbeat session outputs non-standard content (greetings, user guides) instead of HEARTBEAT_OK

  • Impact: OpenClaw Gateway treats these as "content messages" and delivers them to QQ, causing duplication

  • Workaround: Created HEARTBEAT.md to enforce standard output format

  • Expected Fix: Gateway should filter heartbeat outputs before delivery

  • Previous cleanup removed 22,357 duplicate messages (database: 2147MB → 871MB)

  • Created HEARTBEAT.md to filter heartbeat outputs

  • Daily maintenance script runs to clean duplicates

  • Issue persists despite these workarounds

RAW_BUFFERClick to expand / collapse

Description

I am experiencing frequent message duplication in the QQBot channel. Multiple issues contribute to this problem:

1. Heartbeat Session Message Leakage

  • Symptom: Heartbeat session outputs non-standard content (greetings, user guides) instead of HEARTBEAT_OK
  • Impact: OpenClaw Gateway treats these as "content messages" and delivers them to QQ, causing duplication
  • Workaround: Created HEARTBEAT.md to enforce standard output format
  • Expected Fix: Gateway should filter heartbeat outputs before delivery

2. Subagent Reply Leakage

  • Symptom: Subagent completion announcements are incorrectly routed to user QQ
  • Impact: User sees previous task replies mixed with current conversation
  • Example: User asked to create HEARTBEAT.md + submit GitHub Issue. After HEARTBEAT.md was created, the subagent completion announcement leaked to QQ, showing the previous task instructions.

3. Delivery Queue Recovery Race Condition

  • Code Location: /app/dist/delivery-queue-DiT8Zaph.js
  • Mechanism:
    • Messages sent to QQ API succeed, but ACK (rename .json → .delivered) not executed before process crash/restart
    • On restart, recoverPendingDeliveries finds pending delivery and resends
    • Result: Duplicate message delivery
  • Impact: 🔴 Severe - Most likely direct cause of user-reported duplicates

4. WebSocket Reconnect Message Replay

  • Code Location: /app/dist/ws-adapter-CMY-3MVD.js
  • Mechanism:
    • WebSocket reconnects trigger replayFromSequence
    • QQ Bot plugin processes replayed messages as new messages
    • Each reconnect causes duplicate delivery
  • Impact: 🟠 High - Frequent during network instability

5. Thread History Context Injection

  • Code Location: /app/dist/kernel-BXIm_f4L.js
  • Mechanism:
    • ThreadHistoryBody includes bot own previous replies
    • Agent sees its own replies in context
    • Agent may repeat or reference previous content, causing duplicates
  • Impact: 🟠 High - Especially visible in group chats

6. Cron Session Rotation with Pending Delivery

  • Code Location: /app/dist/session-0QcI3GAo.js
  • Mechanism:
    • Cron task detects stale session, rotates to new session
    • Old session pending delivery still in queue
    • Old delivery arrives with new session context → duplicate
  • Impact: 🟡 Medium - Affects cron-triggered tasks

7. Reply Run Registry Race Window

  • Code Location: /app/dist/reply-run-registry-CwZ9EftF.js
  • Mechanism:
    • createReplyOperation uses sessionKey as lock
    • Race window between old run completion and new message arrival
    • If old run delivery completes but clearReplyRunState not executed, new message blocked
    • User resends → old delivery + resend = duplicate
  • Impact: 🟡 Medium - Appears in high-frequency dialogs

8. Heartbeat Polling Trigger

  • Code Location: /app/dist/heartbeat-runtime-DIkZVcyh.js
  • Mechanism:
    • HEARTBEAT_DEFER_WINDOW_MS = 30000 (30 second delay)
    • syncNow uses ackDeliveryId = false
    • If heartbeat waits too long, may force execute and trigger duplicate
  • Impact: 🟡 Medium - Triggers when agent response is slow

Environment

  • OpenClaw Version: 2026.5.22
  • Channel: QQBot
  • Model: xiaomi-coding/mimo-v2.5
  • Platform: Linux (Docker)

Reproduction Steps

  1. Send messages to QQBot
  2. Observe duplicate messages (2-3 copies of same content)
  3. Check delivery queue files in /app/dist/delivery-queue-*.js
  4. Monitor WebSocket reconnect events
  5. Review cron task execution logs

Expected Behavior

  • Messages should be delivered exactly once
  • Subagent completions should not leak to user QQ
  • Heartbeat outputs should be filtered before delivery
  • Delivery queue should use idempotent keys to prevent duplicates

Actual Behavior

  • Messages frequently duplicated (2-3 copies)
  • Previous task replies leak to current conversation
  • Heartbeat outputs cause message duplication
  • No deduplication mechanism in delivery queue

Additional Context

  • Previous cleanup removed 22,357 duplicate messages (database: 2147MB → 871MB)
  • Created HEARTBEAT.md to filter heartbeat outputs
  • Daily maintenance script runs to clean duplicates
  • Issue persists despite these workarounds

Suggested Fixes

  1. Delivery Queue: Add deduplication check in drainQueuedEntry based on (sessionKey, messageId)
  2. WebSocket Replay: Channel plugins should ignore gateway replay messages, or gateway should distinguish "UI client replay" from "channel plugin messages"
  3. Thread History: Limit ThreadHistoryBody length, exclude bot own historical replies
  4. Cron Session: Cancel or invalidate old session pending delivery during rotation
  5. Reply Run: Use microtask for atomic cleanup in clearReplyRunState to reduce race window
  6. Heartbeat Delivery: Enable ackDeliveryId tracking in syncNow to prevent duplicate triggers
  7. Subagent Announcements: Filter subagent completion announcements before delivery to QQ

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

openclaw - 💡(How to fix) Fix Message Duplication in QQBot Channel