TypeError: UrlElicitationRequiredError.__init__() takes from 2 to 3 positional arguments but 4 were given

这个报错通常出现在把 MCP 异常对象做 pickle / cloudpickle 序列化跨进程或跨任务传递时,反序列化会按 Exception.args 调用构造函数,而 UrlElicitationRequiredError.__init__ 期望的位置参数类型与 args 不匹配。优先排查你使

快速结论:这个报错通常出现在把 MCP 异常对象做 pickle / cloudpickle 序列化跨进程或跨任务传递时,反序列化会按 Exception.args 调用构造函数,而 UrlElicitationRequiredError.__init__ 期望的位置参数类型与 args 不匹配。优先排查你使用的 mcp 版本(v1.x 还是 main),并确认异常构造参数与 pickle 重建行为是否一致。

适用环境:Issue 中确认的环境为:Python 3.13、mcp==1.26.0(复现评论中在 mcp==1.27.0 也复现)、fastmcp==3.2.3、cloudpickle==3.1.2;main 分支 commit 3d7b311、v1.x commit 73d458b。其他操作系统、CUDA、显卡信息 Issue 未提供,不做推断。

最快修复方案:暂无确认的一步修复方案。Issue 中验证的方向是为出问题的异常类添加 __reduce__(main 上的 UrlElicitationRequiredError 已按此修复思路推进 PR #2471;v1.x 上 McpError 和 UrlElicitationRequiredError 都需要类似处理)。

注意事项:__reduce__ 方案需同时覆盖构造函数签名,否则仍会在 unpickle 阶段抛错;Issue 中 MCPError 在 main 已修复,但 UrlElicitationRequiredError 在 main 尚未修复,v1.x 两个类都未修复。升级或打补丁前建议先用 Issue 提供的复现脚本确认当前版本的实际行为。

问题场景

用户在 MCP Python SDK 中把 MCP 异常对象(如 McpError、UrlElicitationRequiredError)进行 pickle / cloudpickle 序列化后再反序列化,例如后台任务执行、跨进程传递异常或任务队列场景。Issue 明确说明,即使不使用 Docket/FastMCP 的任务机制,仅用 cloudpickle 做一次 dumps / loads 往返也能复现,因此问题可定位到异常类本身。

报错原文

AttributeError: 'str' object has no attribute 'message'
TypeError: UrlElicitationRequiredError.__init__() takes from 2 to 3 positional arguments but 4 were given

在 v1.x(commit 73d458b)上,两个异常都会失败:McpError 报 AttributeError: 'str' object has no attribute 'message',UrlElicitationRequiredError 报 AttributeError: 'str' object has no attribute 'model_dump'。

原因分析

pickle 重建异常对象时,默认行为是用 cls(*self.args) 调用构造函数。如果异常在初始化时通过 super().__init__(...) 存进 Exception.args 的内容,与 __init__ 期望接收的参数类型或参数个数不一致,反序列化就会失败。

  • v1.x 上的 McpError:__init__ 期望一个 ErrorData 对象,但 super().__init__(error.message) 把纯字符串存进了 args,重建时传入的是 str,访问 error.message 即崩溃('str' object has no attribute 'message')。
  • main 上的 UrlElicitationRequiredError:通过 MCPError.__init__ 存进 args 的是 (code_int, message_str, data_dict) 三个位置参数,总共 4 个(含 self),但该类自己的 __init__ 期望 (elicitations: list[...], message) 即 2 到 3 个位置参数,类型和个数都对不上,于是抛 TypeError: ... takes from 2 to 3 positional arguments but 4 were given。

Issue 作者建议的通用修复方向包括:实现 __reduce__ 用完整载荷重建对象、让 __init__ 兼容字符串 / 规范的 ErrorData,或让构造函数参数与标准异常 pickle 行为保持一致。复现评论者倾向于同时采用 __reduce__ 加宽松初始化作为最稳健方案。

环境排查

  • 确认 mcp 版本:Issue 复现于 mcp==1.26.0,评论中在 mcp==1.27.0 同样复现。v1.x 与 main 的修复状态不同,版本不同结论不同。
  • 确认 cloudpickle 版本(复现环境为 cloudpickle==3.1.2)以及是否直接使用标准库 pickle;Issue 说明两种方式都可复现,不是 cloudpickle 独有的问题。
  • 确认 Python 版本(复现环境为 Python 3.13)。
  • 确认是否使用了 fastmcp==3.2.3 等任务框架;但排查时应先用最小脚本排除任务框架干扰。
  • 确认异常类名:McpError(v1.x)或 MCPError / UrlElicitationRequiredError(main),因为它们在不同分支上的修复进度不同。

解决步骤

  1. 先用 Issue 中的最小复现脚本确认问题归属,排除 cloudpickle 或任务运行器的误判。脚本核心:构造 McpError(ErrorData(code=-32600, message="Authentication Required")),执行 cloudpickle.dumps 后 cloudpickle.loads,观察是否抛 AttributeError: 'str' object has no attribute 'message'。
  2. 确认你所在分支的修复状态:main 分支上 MCPError 已 pickle-safe(复现脚本中 MCPError: PASS),但 UrlElicitationRequiredError 仍失败(TypeError);v1.x 上两个都失败。
  3. 若必须自行打补丁,Issue 中给出的方向是给异常类添加 __reduce__,让其用完整载荷重建。main 上 UrlElicitationRequiredError 的建议补丁为返回 (self.from_error, (self.error,));同时配合宽松的 __init__,把 str 规范化为 ErrorData 作为兜底。
  4. v1.x 上需要给 McpError 和 UrlElicitationRequiredError 都加上 __reduce__,仅修复其中一个不足以解决全部报错。
  5. 若不想自行修改源码,可跟踪 Issue 中提到的修复 PR(PR #2471 为 main 上的 UrlElicitationRequiredError 添加 __reduce__ 及两个类的 pickle 往返测试;PR #2439 是更早期但已停滞的方案),等待合入对应版本。
  6. 临时规避思路(可优先尝试,但 Issue 未给出完整验证):避免让这些 MCP 异常对象跨 pickle 边界传递,改为在边界处提取 error.message 和 error.code 等纯数据再重建。

验证方法

用 Issue 提供的 repro.py(内含 MCPError 和 UrlElicitationRequiredError 两个 pickle 往返测试)在修复后的代码上运行:期望 MCPError 恢复出正确的 message,UrlElicitationRequiredError 恢复出完整的 elicitations 列表和消息,两者均输出 PASS。Issue 中还提到对应的测试用例 test_url_elicitation_required_error_pickle_roundtrip(位于 tests/shared/test_exceptions.py),确认该类测试通过即可认为修复完整。

参考来源

modelcontextprotocol/python-sdk #2431

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 29136

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注