openclaw - 💡(How to fix) Fix [Bug] Feishu streaming card accumulates duplicate text on every tool call — text repeats 3-5x [1 comments, 2 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#78354Fetched 2026-05-07 03:37:56
View on GitHub
Comments
1
Participants
2
Timeline
2
Reactions
2
Author
Timeline (top)
closed ×1commented ×1

When using the built-in Feishu plugin (@openclaw/feishu) with renderMode: "card" and streaming: true, the streaming card accumulates duplicate text every time a tool is called during a multi-tool response. Each new tool invocation causes all previous text to be re-appended in the streaming card, resulting in the same content being displayed 3-5 times.

Root Cause

After inspecting monitor.account-BJ8FoDGL.js in @openclaw/feishu:

Code Example

我现在用 exec 工具查一下系统负载:
🛠️ Exec: uptime

我现在用 exec 工具查一下系统负载:我现在用 exec 工具查看当前内存使用最多的进程:
🛠️ Exec: ps aux --sort=-%mem | head -6

我现在用 exec 工具查一下系统负载:我现在用 exec 工具查看当前内存使用最多的进程:我现在用 read 工具读取配置文件:
📖 Read: from ~/.openclaw/workspace/HEARTBEAT.md

---

// Line ~1461
if (info?.kind === "block") queueStreamingUpdate(text, {
    mode: "delta",  // ← Should be "snapshot"
    dedupeWithLastPartial: true
});
RAW_BUFFERClick to expand / collapse

Description

When using the built-in Feishu plugin (@openclaw/feishu) with renderMode: "card" and streaming: true, the streaming card accumulates duplicate text every time a tool is called during a multi-tool response. Each new tool invocation causes all previous text to be re-appended in the streaming card, resulting in the same content being displayed 3-5 times.

Environment

FieldValue
OpenClaw version2026.5.4 (325df3e)
OSUbuntu 24.04 LTS (Linux 6.17.0-23-generic x64)
Node.jsv22.22.2
Install methodnpm global (openclaw onboard)
Modelbailian/qwen3.6-plus (also tested GLM-5, same behavior)
ChannelFeishu (WebSocket mode)
Plugin@openclaw/feishu (built-in)

Steps to Reproduce

  1. Configure Feishu channel with renderMode: "card" and streaming: true
  2. Send a message that triggers the agent to call multiple tools sequentially (e.g., exec ×3, session_status, read)
  3. Observe the streaming card reply in Feishu

Expected Behavior

Each tool call status (e.g., 🔧 Using: exec...) should appear as a single status line update. The reply text should be displayed once without duplication.

Actual Behavior

Every tool invocation causes all previous reply text to be re-displayed and appended to the card:

我现在用 exec 工具查一下系统负载:
🛠️ Exec: uptime

我现在用 exec 工具查一下系统负载:我现在用 exec 工具查看当前内存使用最多的进程:
🛠️ Exec: ps aux --sort=-%mem | head -6

我现在用 exec 工具查一下系统负载:我现在用 exec 工具查看当前内存使用最多的进程:我现在用 read 工具读取配置文件:
📖 Read: from ~/.openclaw/workspace/HEARTBEAT.md

Each line repeats all previous lines plus the new tool call.

Root Cause Analysis

After inspecting monitor.account-BJ8FoDGL.js in @openclaw/feishu:

1. Block handler uses mode: "delta" (append) instead of mode: "snapshot" (replace)

// Line ~1461
if (info?.kind === "block") queueStreamingUpdate(text, {
    mode: "delta",  // ← Should be "snapshot"
    dedupeWithLastPartial: true
});

2. Double-merge: queueStreamingUpdate + streaming.update both call mergeStreamingText

  • queueStreamingUpdate merges via mergeStreamingText(currentSnapshotText, nextText)
  • Then flushStreamingCardUpdate calls streaming.update(combined)
  • streaming.update() internally calls mergeStreamingText(state.currentText, combined) again

When reasoningText or statusLine changes (tool status updates), the second merge fails to detect overlap and concatenates instead of replacing.

3. deliver(final) doesn't await partialUpdateQueue before closing

clearFlushTimer() in close() cancels pending updates, causing stale content re-delivery.

Related Issues

  • #74143 — feishu streaming card duplicates content when block payloads overlap with partial snapshots (Open)
  • #74146 — PR for #74143 (Open, not merged)
  • #77685 — Feishu streaming card multiple content delivery bugs (Open, filed 2026-05-05)
  • #38943 — Feishu streaming card output produces cumulative token duplication (Closed, possibly a regression)

Suggested Fix

  1. Change block handler from mode: "delta" to mode: "snapshot"
  2. Bypass streaming.update's internal mergeStreamingText in flushStreamingCardUpdate
  3. Add await partialUpdateQueue in deliver(final) before closing
  4. Move clearFlushTimer() in close() to after await this.queue

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