Skip to content

[Bug]: Feishu streaming card renders duplicate text blocks #34108

@Mickey0811

Description

@Mickey0811

Bug type

Behavior bug (incorrect output/state without crash)

Summary

When using Feishu card streaming mode (renderMode: "card" with streaming: true), the same content block is rendered 3+ times in a single message card during streaming updates. The card shows duplicated text that grows with each streaming update cycle.

Steps to reproduce

  1. Configure Feishu channel with renderMode: "card" and streaming: true (default).
  2. Send a message that triggers a long response with structured content (markdown lists, headings, etc.).
  3. Observe the streamed card content in the Feishu chat.

Expected behavior

Card content should update incrementally without duplication — each streaming update replaces the previous content with the latest cumulative text.

Actual behavior

The same text block appears 3+ times in the card. Each streaming update cycle appends the full cumulative text again instead of replacing it, causing the content to grow multiplicatively.

OpenClaw version

2026.3.2

Operating system

macOS 15.4

Install method

pnpm dev

Logs, screenshots, and evidence

Root cause is in extensions/feishu/src/reply-dispatcher.ts, the local mergeStreamingText function.

onPartialReply always passes cumulative text (the full assistant output so far), not deltas. The merge function checks nextText.startsWith(streamText) to detect cumulative payloads, but this check fails when:

  1. Block deliver payloads (info.kind === "block") call queueStreamingUpdate(text) with text that has been processed differently (e.g., directive stripping changes offsets).
  2. The cumulative text contains streamText but doesn't start with it (e.g., a leading newline or whitespace difference).

When the startsWith check fails, the function falls through to streamText += nextText, which appends the entire cumulative text to the existing buffer — causing the full content to appear multiple times.

Impact and severity

Affected: All Feishu users with card streaming enabled (the default configuration)
Severity: Medium (renders garbled/duplicated output but doesn't block functionality)
Frequency: Intermittent — depends on response length, content structure, and timing of block vs partial payloads
Consequence: Poor user experience with unreadable duplicated card content

Additional information

The fix adds three improvements to mergeStreamingText:

  1. nextText.includes(streamText) check — handles cumulative payloads where streamText appears within nextText but not at the start.
  2. streamText.includes(nextText) check — handles cases where the incoming text is already fully contained.
  3. Overlap detection in the append fallback — finds the longest suffix-prefix overlap to avoid partial duplication when genuinely new text arrives.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions