openclaw - ✅(Solved) Fix Feishu: card fails with 'table number over limit' — should fallback or render tables as images [1 pull requests, 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#43690Fetched 2026-04-08 00:17:09
View on GitHub
Comments
0
Participants
1
Timeline
3
Reactions
0
Participants
Timeline (top)
referenced ×2cross-referenced ×1

Error Message

[feishu] streaming start failed: Error: Create card request failed with HTTP 400 [feishu] feishu[default] final reply failed: AxiosError: Request failed with status code 400

Fix Action

Fixed

PR fix notes

PR #50429: fix(feishu): fall back to plain text when card delivery fails

Description (problem / solution / changelog)

Summary

  • Problem: When the agent response contains many markdown tables, Feishu rejects the interactive card with "card table number over limit" (HTTP 400 / code 230099). The reply is silently dropped and the user receives nothing in Feishu, even though the response is visible in the control UI.
  • Root cause: In reply-dispatcher.ts, the card delivery path (sendStructuredCardFeishu) does not catch errors. When the Feishu API rejects the card, the error propagates up and the reply is lost.
  • Fix: Wrap the card delivery in a try/catch. On failure, log a warning and retry as plain text via sendMessageFeishu(), applying convertMarkdownTables() to transform tables into a text-friendly format before sending.
  • What did NOT change: Streaming card path (CardKit API) is not affected — it updates individual card elements rather than creating full cards, so it does not hit the table limit.

Change Type

  • Bug fix

Scope

  • Feishu/Lark channel

Linked Issue

  • Closes #43690

User-visible / Behavior Changes

Before: Agent response with many tables → Feishu card fails silently → user sees nothing:

[feishu] streaming start failed: Error: Create card request failed with HTTP 400
[feishu] feishu[default] final reply failed: AxiosError: Request failed with status code 400

After: Card fails → automatic fallback to plain text with tables converted:

feishu[main]: card send failed, falling back to text: Error: card table number over limit

User receives the response as a regular text message with tables rendered as bullet lists or code blocks (depending on markdownTableMode config).

Security Impact

None. No new permissions, no network changes, no secrets handling.

Evidence

  • 31 tests passing (29 existing + 2 new fallback-specific tests)
✓ extensions/feishu/src/reply-dispatcher.test.ts (31 tests) 10ms
  ✓ falls back to plain text when card send fails (e.g. table limit exceeded)
  ✓ card fallback does not trigger when card send succeeds

Compatibility

  • Backward compatible. Only adds error handling around existing card delivery.
  • No config changes needed. Fallback uses existing markdownTableMode setting.

Failure Recovery

  • Revert: Remove the try/catch block around sendStructuredCardFeishu in deliver().

Risks

Minimal — the fallback path uses the same sendMessageFeishu function already used for non-card delivery.

[AI-assisted development by OpenClaw agent 虾干 🦐]

Changed files

  • docs/tools/plugin.md (modified, +7/-7)
  • extensions/feishu/src/reply-dispatcher.test.ts (modified, +78/-0)
  • extensions/feishu/src/reply-dispatcher.ts (modified, +43/-18)

Code Example

Create card request failed with HTTP 400
code: 230099, msg: card table number over limit

---

[feishu] streaming start failed: Error: Create card request failed with HTTP 400
[feishu] feishu[default] final reply failed: AxiosError: Request failed with status code 400

---

{
  "code": 230099,
  "msg": "Failed to create card content, ext=ErrCode: 11310; ErrMsg: card table number over limit"
}
RAW_BUFFERClick to expand / collapse

Problem

When the agent's response contains multiple markdown tables, sending via Feishu interactive card fails with:

Create card request failed with HTTP 400
code: 230099, msg: card table number over limit

Both the streaming card creation and the final reply fail. There is no fallback — the user sees the response in the control UI but receives nothing in Feishu.

Reproduction

  1. Send a prompt to the bot in a Feishu group that elicits a response with many markdown tables (e.g., "generate a comprehensive data table with multiple categories")
  2. The bot generates the response (visible in the web UI)
  3. Feishu delivery fails silently — no message is sent to the chat

Relevant logs

[feishu] streaming start failed: Error: Create card request failed with HTTP 400
[feishu] feishu[default] final reply failed: AxiosError: Request failed with status code 400

Error detail from Feishu API:

{
  "code": 230099,
  "msg": "Failed to create card content, ext=ErrCode: 11310; ErrMsg: card table number over limit"
}

Suggestion

  1. Fallback: When card creation fails due to table limits, fall back to plain text (renderMode: "raw") for that specific message instead of failing silently.
  2. Render tables as images: Convert markdown tables into images (e.g., render as HTML table → screenshot as PNG) and send them as image attachments in Feishu. This preserves the visual table layout while avoiding the card table limit entirely.
  3. Table conversion: Apply convertMarkdownTables() in the card path as well (currently only applied in the non-card text path), so tables are converted to bullet lists or code blocks before card creation.

Environment

  • OpenClaw version: 2026.3.8
  • Channel: Feishu (websocket mode)
  • Model: anthropic/claude-sonnet-4-6
  • renderMode: auto (default)

extent analysis

Fix Plan

To address the issue of Feishu interactive card failures due to excessive markdown tables, we will implement a fallback to plain text when the card creation fails.

Step-by-Step Solution

  1. Detect Card Creation Failure: Check for the specific error code 230099 and message card table number over limit in the Feishu API response.
  2. Fallback to Plain Text: When the error is detected, switch the renderMode to "raw" for the specific message.
  3. Implement Table Conversion: Apply convertMarkdownTables() to convert tables to bullet lists or code blocks before card creation.

Example Code

// Check for card creation failure
if (error.code === 230099 && error.msg.includes('card table number over limit')) {
  // Fallback to plain text
  renderMode = 'raw';
  // Convert markdown tables
  message = convertMarkdownTables(message);
  // Resend the message
  sendFeishuMessage(message, renderMode);
}

// Function to convert markdown tables
function convertMarkdownTables(message) {
  // Implement table conversion logic here
  // For example, using a library like markdown-it
  const markdown = require('markdown-it')();
  const html = markdown.render(message);
  // Convert HTML tables to bullet lists or code blocks
  const convertedMessage = html.replace(/<table>.*?<\/table>/gs, (match) => {
    // Convert table to bullet list
    const tableHtml = match.replace(/<table>/g, '').replace(/<\/table>/g, '');
    const rows = tableHtml.split('</tr>');
    const bulletList = rows.map((row) => {
      const cells = row.replace(/<tr>/g, '').replace(/<\/tr>/g, '').split('</td>');
      return `- ${cells.map((cell) => cell.replace(/<td>/g, '')).join(', ')}`;
    }).join('\n');
    return bulletList;
  });
  return convertedMessage;
}

Verification

To verify the fix, send a prompt to the bot that elicits a response with multiple markdown tables and check if the message is delivered successfully in Feishu.

Extra Tips

  • Ensure the convertMarkdownTables() function is correctly implemented to handle different table formats and edge cases.
  • Consider adding a limit to the number of tables allowed in a single message to prevent excessive processing.
  • Monitor the Feishu API response for any changes to the error codes or messages.

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