openclaw - ✅(Solved) Fix [Bug]: Feishu 通道 card 字段被错误标记为必填,无法发送纯媒体消息 [1 pull requests, 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#53656Fetched 2026-04-08 01:25:14
View on GitHub
Comments
1
Participants
2
Timeline
10
Reactions
0
Timeline (top)
cross-referenced ×4referenced ×3labeled ×2commented ×1

在 Feishu(飞书)通道使用 message 工具发送纯媒体消息(图片/文件/音频)时,会触发 schema 验证错误:

Validation failed for tool "message":
  - card: must have required property 'card'

Error Message

if (card && mediaUrl) throw new Error(Feishu ${ctx.action} does not support card with media.); if (!card && !text && !mediaUrl) throw new Error(Feishu ${ctx.action} requires text/message, media, or card.);

Root Cause

在 Feishu(飞书)通道使用 message 工具发送纯媒体消息(图片/文件/音频)时,会触发 schema 验证错误:

Validation failed for tool "message":
  - card: must have required property 'card'

Fix Action

Fixed

PR fix notes

PR #53800: fix(message-tool): make channel plugin schema properties optional

Description (problem / solution / changelog)

Summary

Channel plugin schema contributions (e.g. Feishu's card field) were merged into the message tool schema via extraProperties without wrapping in Type.Optional(), making them required by default in the Typebox Object schema.

This caused the Feishu card field to be a required property of the message tool, breaking all non-card send actions (plain text, image, file) with:

The error confirmed this affected ALL proactive Feishu sends — text messages, images, and files — and was reported independently by two users as issues #53656 and #53295.

Fix

In buildMessageToolSchemaProps(), wrap each extraProperties value in Type.Optional() before merging into the tool schema, so channel plugin fields are always optional:

...(options.extraProperties
  ? Object.fromEntries(
      Object.entries(options.extraProperties).map(([k, v]) => [k, Type.Optional(v)]),
    )
  : {}),

This is the correct semantic: channel plugin fields like card, media, buffer, etc. are always optional — the message tool decides which to use based on the action type.

Testing

  • ✅ Format check: all 8841 files
  • ✅ Lint: 0 warnings, 0 errors
  • ✅ All lint:tmp checks pass
  • pnpm check passes (excluding pre-existing TS2883 inference warnings in unrelated test files)

Related Issues

Fixes #53656 Fixes #53295

Changed files

  • src/agents/tools/message-tool.ts (modified, +8/-1)

Code Example

Validation failed for tool "message":
  - card: must have required property 'card'

---

{
  "name": "message",
  "parameters": {
    "action": "send",
    "channel": "feishu",
    "media": "/tmp/test.jpg",
    "caption": "测试图片"
  }
}

---

Validation failed for tool "message":
  - card: must have required property 'card'

---

错误信息:
Validation failed for tool "message":
  - card: must have required property 'card'
触发调用:
{
  "action": "send",
  "channel": "feishu",
  "media": "/tmp/test.jpg",
  "caption": "test"
}
完整错误堆栈位置:
OpenClaw dist/channel-D60N8mHW.js
describeFeishuMessageTool() 返回的 schema
mergeToolSchemaProperties() 合并到全局 schema
Zod 验证时报错

---

// 目前错误的 schema
schema: enabled ? { properties: { card: createMessageToolCardSchema() } } : null

// Feishu handler 正确的逻辑
if (card && mediaUrl) throw new Error(`Feishu ${ctx.action} does not support card with media.`);
if (!card && !text && !mediaUrl) throw new Error(`Feishu ${ctx.action} requires text/message, media, or card.`);

---

// 第 345 行和第 366 行修改为
schema: enabled ? { properties: { card: Type.Optional(createMessageToolCardSchema()) }, required: [] } : null
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Summary

在 Feishu(飞书)通道使用 message 工具发送纯媒体消息(图片/文件/音频)时,会触发 schema 验证错误:

Validation failed for tool "message":
  - card: must have required property 'card'

Steps to reproduce

  1. 配置好 Feishu 通道,确保 app 有发送消息权限
  2. 调用 message 工具发送图片/文件,不提供 card 参数:
{
  "name": "message",
  "parameters": {
    "action": "send",
    "channel": "feishu",
    "media": "/tmp/test.jpg",
    "caption": "测试图片"
  }
}
  1. 验证错误在 schema 阶段就被拦截,没有到达 Feishu handler 逻辑

Expected behavior

根据 Feishu 通道 handler 的业务逻辑,send 动作支持三种互斥的消息类型,不需要同时提供:

  1. card:交互式卡片消息
  2. media:媒体文件消息
  3. text:纯文本消息

发送纯媒体消息时不应该要求提供 card 字段。

Actual behavior

schema 验证直接失败,错误信息:

Validation failed for tool "message":
  - card: must have required property 'card'

OpenClaw version

OpenClaw 版本:2026.3.23-1 / 2026.3.23-2

Operating system

Ubuntu 24.04 WSL2 / macOS 均复现Node.js 版本:22.16.0

Install method

npm全局

Model

minimax-2.7

Provider / routing chain

WSL2 localhost (127.0.0.1:7890) → Windows Clash → open.feishu.cn

Additional provider/model setup details

No response

Logs, screenshots, and evidence

错误信息:
Validation failed for tool "message":
  - card: must have required property 'card'
触发调用:
{
  "action": "send",
  "channel": "feishu",
  "media": "/tmp/test.jpg",
  "caption": "test"
}
完整错误堆栈位置:
OpenClaw dist/channel-D60N8mHW.js
  → describeFeishuMessageTool() 返回的 schema
  → mergeToolSchemaProperties() 合并到全局 schema
  → Zod 验证时报错

Impact and severity

影响范围:所有使用 Feishu 通道的用户 功能缺失:无法通过 message 工具发送图片/文件/音频 严重程度:Medium(功能损坏,但有临时绕过方案) 证据:

  1. schema 验证层拦截,不到达 handler
  2. 临时绕过方案可行(直接调 API),说明飞书 API 本身正常
  3. 工具层 schema 和 handler 逻辑不一致

Additional information

根因分析

位于 /usr/local/lib/node_modules/openclaw/dist/channel-D60N8mHW.js 中的 describeFeishuMessageTool() 函数返回的 schema 中,card 字段没有被标记为 Optional,在 schema 合并时被判定为必填字段,和 handler 逻辑冲突:

// 目前错误的 schema
schema: enabled ? { properties: { card: createMessageToolCardSchema() } } : null

// Feishu handler 正确的逻辑
if (card && mediaUrl) throw new Error(`Feishu ${ctx.action} does not support card with media.`);
if (!card && !text && !mediaUrl) throw new Error(`Feishu ${ctx.action} requires text/message, media, or card.`);

临时解决办法

  1. 本地补丁:修改 dist 文件,显式标记 card 为 Optional:
// 第 345 行和第 366 行修改为
schema: enabled ? { properties: { card: Type.Optional(createMessageToolCardSchema()) }, required: [] } : null

⚠️ 此补丁在 npm update 后会被覆盖。

  1. 绕过方案:不使用 OpenClaw message 工具,直接调用 Feishu 原生 API 发送媒体消息:
    • POST /open-apis/auth/v3/tenant_access_token/internal 获取 access_token
    • POST /open-apis/im/v1/files 上传媒体获取 file_key
    • POST /open-apis/im/v1/messages 发送 msg_type=file/image 消息

建议修复方案

修改 describeFeishuMessageTool() 返回的 schema,显式将 card 字段标记为 Optional,和 handler 逻辑保持一致。

extent analysis

Fix Plan

To resolve the issue, we need to modify the describeFeishuMessageTool() function to mark the card field as optional in the schema. Here are the steps:

  • Locate the describeFeishuMessageTool() function in the channel-D60N8mHW.js file.
  • Update the schema to mark the card field as optional using Type.Optional():
schema: enabled ? { 
  properties: { 
    card: Type.Optional(createMessageToolCardSchema()) 
  }, 
  required: [] 
} : null
  • Verify that the required property is set to an empty array [] to ensure that no fields are marked as required by default.

Code Changes

The updated code should look like this:

// Updated schema with card marked as optional
schema: enabled ? { 
  properties: { 
    card: Type.Optional(createMessageToolCardSchema()), 
    // Other properties...
  }, 
  required: [] 
} : null

Note that this change should be made in the source code of the openclaw package, not in the compiled dist files.

Verification

To verify that the fix worked, try sending a media message using the message tool without providing the card parameter. The schema validation should no longer fail, and the message should be sent successfully.

Extra Tips

  • Make sure to update the openclaw package to the latest version after making the changes to ensure that any future updates do not overwrite the fix.
  • Consider submitting a pull request to the openclaw repository with the updated code to ensure that the fix is included in future releases.

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…

FAQ

Expected behavior

根据 Feishu 通道 handler 的业务逻辑,send 动作支持三种互斥的消息类型,不需要同时提供:

  1. card:交互式卡片消息
  2. media:媒体文件消息
  3. text:纯文本消息

发送纯媒体消息时不应该要求提供 card 字段。

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING