![[Bug] iOS app: MCP (HTTP) tool calls fail on self-hosted server — message.update rejected by ZodError (error.type required, app omits it)](https://www.chat-gpts.plus/wp-content/uploads/2026/07/16861-3567d589.jpg)
[Bug] iOS app: MCP (HTTP) tool calls fail on self-hosted server — message.update rejected by ZodError (error.type required, app omits it)
快速结论:该问题仅发生在 iOS App(React Native 客户端)上,调用 Streamable HTTP 类型的 MCP 工具时,客户端构建的 error 对象缺少必需的 error.type 字段,导致服务端 message.update 的 Zod 校验失败。Web 端(桌面/移动浏览器)不受影响。优先排查 iOS 客户端 MCP 工具错误处理路径中 type 字段的默认值是否被遗漏。
问题场景
在 LobeChat iOS App(App Store 版本)上,对自托管 Docker 服务器(lobehub/lobehub:2.2.9)发起 Streamable HTTP 类型的 MCP 工具调用时,工具调用无法执行。同样的 MCP 工具、同一账号、同一自托管服务器,在 Web 桌面浏览器和 Web 移动浏览器上正常工作。
报错原文
Error in tRPC handler (mobile) on path: message.update, type: mutation
Error [TRPCError]: [
{
"code": "invalid_union",
"unionErrors": [
{ "issues": [ { "code": "invalid_type", "expected": "string", "received": "undefined",
"path": ["value","error","type"], "message": "Required" } ], "name": "ZodError" },
{ "issues": [ { "code": "invalid_type", "expected": "number", "received": "undefined",
"path": ["value","error","type"], "message": "Required" } ], "name": "ZodError" }
],
"path": ["value","error","type"],
"message": "Invalid input"
}
]
原因分析
服务端 ChatMessageErrorSchema(定义在 packages/types/src/message/common/base.ts)中 type 字段是必需的,类型为 z.union([z.string(), z.number()]),没有 .optional()。iOS 客户端在 MCP 工具调用失败时构建的错误对象缺少 type 字段(type: undefined),导致 message.update 的 Zod 联合类型校验失败。Web 客户端可能走了不同的代码路径或遇到了不同的错误形状,恰好包含了 type 字段。
具体来说,MCP 工具错误构造路径中,错误对象是这样构建的:
{
message: (mcpResult.error as any)?.message ?? 'MCP tool call failed',
type: (mcpResult.error as any)?.type
}
当 mcpResult.error.type 为 undefined 时,type: undefined 违反了 Zod 联合类型的校验。虽然在 updateMessageError 中存在对缺失 type 使用 'ApplicationRuntimeError' 作为默认值的回退模式,但该回退并未应用在 MCP 错误处理路径中。
环境排查
- 服务器版本:自托管 Docker
lobehub/lobehub:2.2.9或更高版本(Issue 基于此版本) - 客户端类型:iOS App(App Store 最新版本,2026-07-08 时)—— 仅 iOS 受影响
- MCP 工具类型:Streamable HTTP 类型(可访问的公共 URL)
- 登录方式:已启用 OIDC 登录
- 依赖检查:
packages/types/src/message/common/base.ts中ChatMessageErrorSchema.type是否为必需字段(自 #9952 起一直为必需)
解决步骤
- 定位 iOS 客户端 MCP 工具错误构造路径。Issue 中确认了 MCP 工具调用失败时错误对象构建的位置。
- 在构建错误对象时,为
type字段添加一个默认值回退,例如:type: (mcpResult.error as any)?.type ?? 'MCPToolCallError'。 - 该修复方案与代码库中其他位置已有的防御性回退模式(
updateMessageError中默认使用'ApplicationRuntimeError')保持一致。 - 备选方案:在服务端
ChatMessageErrorSchema中使type字段变为可选(设置为.optional()),并设定合理的默认值。但 Issue 指出目前type是唯一一个没有.optional()的字段,且从 #9952 起一直如此,因此客户端修复优先级更高。
验证方法
- 应用修复后,在 iOS App 上使用相同的自托管服务器和相同的 MCP 工具重复复现步骤。
- 确认服务端
message.update不再报 ZodError,且 MCP 工具调用能正常执行并返回结果。 - 确认修复后 Web 端(桌面/移动浏览器)功能仍然正常,不受影响。
- 检查服务端日志,确认
toolExecution/callTool日志正常出现,而不是仅出现message.update的错误日志。



