Skip to content

Fix the limitation on the number of tables in cards caused by Feishu#1736

Merged
yinwm merged 2 commits intosipeed:mainfrom
opcache:fix/issue-1727-feishu
Mar 19, 2026
Merged

Fix the limitation on the number of tables in cards caused by Feishu#1736
yinwm merged 2 commits intosipeed:mainfrom
opcache:fix/issue-1727-feishu

Conversation

@opcache
Copy link
Contributor

@opcache opcache commented Mar 18, 2026

📝 Description

This PR addresses the Feishu API error triggered when the number of Markdown tables in an Interactive Card exceeds the platform limit. The error manifests as code=230099 msg=Failed to create card content, ext=ErrCode: 11310; ErrMsg: card table number over limit.

Key modifications:

  1. Updated the Send method in feishu_64.go (lines 115-147) to implement auto-downgrade logic: prioritize card-based message delivery, detect table limit errors, and automatically fall back to plain text delivery if the error is triggered.
  2. Added a new sendText helper method (lines 735-762) to handle plain text message sending via Feishu's MsgTypeText API.
  3. Imported the strings package for error message pattern matching and added warning logging to facilitate troubleshooting of table limit issues.

Implementation Logic

1st Attempt: Try sending Interactive Card
    ↓ Success
Return success

    ↓ Failure (Error Code 11310)
2nd Attempt: Try sending plain Text message
    ↓ Success
Return success (with message format downgraded)

    ↓ Failure
Return error

🗣️ Type of Change

  • 🐞 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 📖 Documentation update
  • ⚡ Code refactoring (no functional changes, no api changes)

🤖 AI Code Generation

  • 🤖 Fully AI-generated (100% AI, 0% Human)
  • 🛠️ Mostly AI-generated (AI draft, Human verified/modified)
  • 👨‍💻 Mostly Human-written (Human lead, AI assisted or none)

🔗 Related Issue

Fixes #XXX (replace XXX with the actual issue number; remove this line if no related issue exists)

📚 Technical Context (Skip for Docs)

🧪 Test Environment

  • Hardware: PC
  • OS: Ubuntu 24.04 / WIN10
  • Model/Provider: Feishu Open Platform API v4
  • Channels: Feishu

📸 Evidence (Optional)

Click to view Logs/Screenshots

Error Log Before Fix

feishu api error (code=230099 msg=Failed to create card content, ext=ErrCode: 11310; ErrMsg: card table number over limit)
plaintext

Warning Log After Fix

WARNING: Feishu card table limit exceeded, downgrading to plain text: feishu api error (code=230099 msg=Failed to create card content, ext=ErrCode: 11310; ErrMsg: card table number over limit)
plaintext

Successful Delivery Confirmation

2026-03-18 10:00:00 [INFO] Feishu plain text message sent successfully, message ID: msg_xxx
plaintext

☑️ Checklist

  • My code/docs follow the style of this project.
  • I have performed a self-review of my own changes.
  • I have updated the documentation accordingly.

Copilot AI review requested due to automatic review settings March 18, 2026 08:41
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Improves Feishu outbound message reliability by falling back to plain-text messages when Interactive Card delivery fails due to specific card limitations.

Changes:

  • Add a fallback flow in FeishuChannel.Send to retry as plain text when card sending fails with certain “card limit” errors.
  • Introduce sendText helper to send Feishu text messages via the same IM message create API.
  • Add minimal logging for the fallback path and import strings for error matching.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +139 to +143
// Check if error is due to card limitations (e.g., table limit exceeded)
errMsg := err.Error()
isCardLimitError := strings.Contains(errMsg, "table") ||
strings.Contains(errMsg, "230099") ||
strings.Contains(errMsg, "11310")
Comment on lines +145 to +149
if isCardLimitError {
logger.WarnCF("feishu", "Card send failed (table limit), falling back to text message", map[string]any{
"chat_id": msg.ChatID,
"error": errMsg,
})
Comment on lines +139 to +143
// Check if error is due to card limitations (e.g., table limit exceeded)
errMsg := err.Error()
isCardLimitError := strings.Contains(errMsg, "table") ||
strings.Contains(errMsg, "230099") ||
strings.Contains(errMsg, "11310")
Copy link
Collaborator

@yinwm yinwm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

Thanks for implementing the fallback logic! The approach is solid.

One Issue to Fix

The error detection pattern is too broad:

isCardLimitError := strings.Contains(errMsg, "table") ||
    strings.Contains(errMsg, "230099") ||
    strings.Contains(errMsg, "11310")

The keyword "table" is too generic and could match unrelated error messages (e.g., database errors containing "table"). This might trigger unnecessary fallbacks.

Suggestion: Only match the specific error code:

isCardLimitError := strings.Contains(errMsg, "11310")

Or be more precise with the pattern:

isCardLimitError := strings.Contains(errMsg, "ErrCode: 11310")

Other than that, LGTM! 👍

@opcache
Copy link
Contributor Author

opcache commented Mar 19, 2026

@yinwm Updated to only match error code 11310

@sipeed-bot sipeed-bot bot added type: bug Something isn't working domain: channel labels Mar 19, 2026
Copy link
Collaborator

@yinwm yinwm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! The fallback logic is correct and handles the card table limit error gracefully.

Two minor informational notes for future consideration:

  1. The error wrapping in sendText drops the original error details — consider fmt.Errorf("feishu send text: %w: %v", channels.ErrTemporary, err) for better debugging
  2. EditMessage and SendPlaceholder also use card sending and could hit the same 11310 error — consider adding similar fallback if needed

These are minor and don't block the merge.

@yinwm yinwm merged commit e3cc5b1 into sipeed:main Mar 19, 2026
4 checks passed
tong3jie pushed a commit to tong3jie/picoclaw that referenced this pull request Mar 20, 2026
…ipeed#1736)

* Fix the limitation on the number of tables in cards caused by Feishu

* Only match the error code 11310
@Orgmar
Copy link
Contributor

Orgmar commented Mar 20, 2026

@opcache Smart approach on the Feishu card table limit fix. Auto-downgrading to plain text when the API rejects the card keeps message delivery reliable without losing content. The fallback flow is clean and the warning logging makes it easy to spot when downgrades happen.

We're building a PicoClaw Dev Group on Discord for contributors to collaborate. If you're interested, drop an email to support@sipeed.com with subject [Join PicoClaw Dev Group] opcache and we'll get you the invite link!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain: channel type: bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants