Skip to content

[Bug]: Feishu CardKit streaming card appends full accumulated text on each update instead of replacing #82417

@chendehao

Description

@chendehao

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

When streaming is enabled for Feishu with renderMode "card", each CardKit streaming card update causes the Feishu client to append the full accumulated text to the existing content instead of replacing it, resulting in severe text duplication visible to the user.

Steps to reproduce

  1. Configure Feishu channel with streaming: true and renderMode: "card".
  2. Send a message that triggers a multi-step agent response with tool calls (e.g. file writes, shell commands, patch applications).
  3. Observe the Feishu streaming card: each time the agent completes a tool call and generates more text, the entire accumulated response is appended to the card, creating duplicated blocks of text.

Expected behavior

Each CardKit streaming card update should replace the element content cleanly. The card should show only the latest accumulated text without duplication.

Actual behavior

The Feishu CardKit client appends the new content to the existing card content on each update. The result is a card that contains the same text repeated N times (once for each update), growing progressively longer as the agent performs more operations.

The CardKit API endpoint PUT /cardkit/v1/cards/{card_id}/elements/content/content is called with the full accumulated text and an incrementing sequence number. The API should replace the element content, but the Feishu client renders it as appended text.

OpenClaw version

2026.5.16-beta.1 (dc8790d) 但存在于迄今所有版本

Operating system

Windows 11 Pro 10.0.26200

Install method

npm global

Model

mimo-v2.5 (issue is model-independent; it is a channel rendering bug)

Provider / routing chain

openclaw -> silicon-flow -> mimo-v2.5

Additional provider/model setup details

No response

Logs, screenshots, and evidence

The streaming update flow in OpenClaw (extensions/feishu/src/streaming-card.ts):

1. FeishuStreamingSession.start() creates a CardKit card with streaming_mode: true.
2. FeishuStreamingSession.update(text) is called with the full accumulated text on each LLM streaming chunk.
3. Inside update(), mergeStreamingText() correctly identifies that each new text extends the previous (e.g. "A" -> "AB" -> "ABC"), so no incorrect concatenation occurs.
4. updateCardContent() sends PUT /cardkit/v1/cards/{card_id}/elements/content/content with:
   - content: the full accumulated text
   - sequence: incrementing integer (1, 2, 3, ...)
   - uuid: unique per update (s_{cardId}_{sequence})
5. The Feishu client receives the update but renders the new content as appended to the existing content, not as a replacement.

The merge logic (mergeStreamingText) was verified to be working correctly - each new partial reply text starts with the previous text, so the merge returns the new text without concatenation. The bug is NOT in the text merging.

Increasing STREAMING_UPDATE_THROTTLE_MS from 160ms to 1000ms and STREAMING_SIGNIFICANT_DELTA_CHARS from 18 to 50 did not resolve the duplication.

Hermes (a separate agent framework) uses the standard Feishu im.v1.message.update API (not CardKit) with simple full-text replacement and does not exhibit this issue.

Impact and severity

Affected: All Feishu users with streaming enabled and renderMode "card"
Severity: High — streaming output is unusable due to massive text duplication
Frequency: Always reproducible with multi-step agent responses
Consequence: Each tool call causes the entire accumulated response to be duplicated in the card, making the output unreadable

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingbug:behaviorIncorrect behavior without a crash

    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