Bug: MCPAdapter test fails on Windows due to strict POSIX error assertion

这个报错是 LangChain 在 Windows 上运行 MCPAdapter 单元测试时触发的测试断言失败,不是实际的 URL 校验逻辑出错。优先排查点只有一处:测试用例是否硬绑定了 POSIX 下的 Pydantic 报错文案 "not a valid URL"。

快速结论:这个报错是 LangChain 在 Windows 上运行 MCPAdapter 单元测试时触发的测试断言失败,不是实际的 URL 校验逻辑出错。优先排查点只有一处:测试用例是否硬绑定了 POSIX 下的 Pydantic 报错文案 “not a valid URL”。

适用环境:操作系统:Windows;Python 版本:3.12.13;受影响包:langchain;相关模块:langchain.mcp 中的 MCPAdapter;相关测试文件:tests/unit_tests/mcp/test_adapter.py;涉及的测试用例:test_a_string_naming_a_local_script_is_refused。

最快修复方案:暂无确认的一步修复方案。Issue 中讨论的处理方向是“仅改测试、不改校验逻辑”:在该测试的 pytest.raises(match=…) 中放宽断言,接受 “not a valid URL” 或 “has scheme” 两种拒绝信息中的任意一种,而不是去修改 _validate_url_target。

注意事项:放宽断言只适用于该测试用例本身,不能据此认为生产代码的校验逻辑需要统一报错文案;Issue 评论明确指出,C:\… 这类盘符路径被拒绝是既有行为,且已有 test_strings_parsing_as_non_http_urls_are_refused 对其做了固定断言,统一文案会牵动生产 guard。相关 PR(#40417、#40437)在 Issue 讨论中并未确认已合并,具体采用哪种正则写法请以实际合入的版本为准。

问题场景

在 Windows 环境下运行 LangChain 的 MCPAdapter 单元测试(tests/unit_tests/mcp/test_adapter.py)时,测试用例 test_a_string_naming_a_local_script_is_refused 失败。该测试的本意是验证:把本地脚本路径以字符串形式传给 MCPAdapter 时会被拒绝(安全防护生效)。用户按复现步骤构造一个临时目录下的 server.py 路径,调用 MCPAdapter(str(script)),期望抛出包含 “not a valid URL” 的 ValueError。

问题只在 Windows 上出现;Issue 正文说明该测试在 POSIX 上可以正常通过。用户通常是在本地 Windows 开发机或 windows-latest CI 矩阵中跑这个测试文件时撞上的。

报错原文

AssertionError: Regex pattern did not match.
Expected regex: 'not a valid URL'
Actual message: "MCP target 'C:\\Users\\...\\Temp\\tmp\\server.py' has
scheme 'c', but a string target must be an
http or https URL.

原因分析

原因是平台差异导致底层 Pydantic 的解析结果不同,而测试只断言了 POSIX 下的报错文案:

  • 在 POSIX 上,像 /tmp/server.py 这样的绝对路径无法通过 Pydantic 的 AnyUrl 校验,抛出的 ValueError 中包含 “not a valid URL”,与测试断言一致。
  • 在 Windows 上,像 C:\Users\…\server.py 这样的路径会被 Pydantic 解析成一个“合法 URL”,盘符被当作 scheme(例如 scheme 为 “c”)。此时拦截动作由 MCPAdapter 自身的 http/https scheme 检查完成,报错文案变成 “has scheme ‘c'”。

也就是说,安全机制在两个平台上都正确拒绝了本地脚本路径,只是拒绝路径和报错文案不同。测试断言写死了 POSIX 专有的错误字符串,因此在 Windows 上失败。

环境排查

  • 确认操作系统是否为 Windows(本次失败为 Windows 专有问题)。
  • 确认 Python 版本(Issue 报告为 3.12.13)。
  • 确认运行的测试文件为 tests/unit_tests/mcp/test_adapter.py,失败用例为 test_a_string_naming_a_local_script_is_refused。
  • 确认 langchain 包来源与版本,是否在已安装包内运行测试而非仓库源码。
  • 确认 pydantic 版本,因为报错文案由 Pydantic 的 AnyUrl 校验产生。
  • 确认临时目录所在盘符,Issue 评论特别提醒:不可假设一定在 C: 盘。
  • 确认 CI 是否跑在 windows-latest 矩阵上。

解决步骤

  1. 先在发生失败的环境定位到该测试用例,确认失败信息确实是 “has scheme ‘c’…” 而不是其他报错。
  2. 确认这是“测试断言过严”而非生产逻辑缺陷:在 POSIX 上同一路径应报 “not a valid URL”,在 Windows 上报 “has scheme …”,两条路径都是合法拒绝。
  3. 修改测试断言(不改 _validate_url_target):在该测试的 pytest.raises(ValueError, match=…) 中,把正则改为同时覆盖 “not a valid URL” 和 “has scheme” 两种拒绝信息中的任意一种。
  4. 由于临时目录盘符不固定,正则中匹配盘符时不要写死 c,应匹配任意盘符,避免在非 C: 盘上再次失败。
  5. 不要为了让两条报错统一而去改 _validate_url_target:Issue 评论指出 test_strings_parsing_as_non_http_urls_are_refused 已固定断言 C:\… 会被 “has scheme ‘c'” 拒绝,统一文案会与既有测试冲突。
  6. 若需要提交 PR,注意 Issue 评论提到:外部 PR 作者若未被分配到该 Issue,可能被 issue-link 检查自动关闭,因此需要先获得 assign 再开 PR。

验证方法

在 Windows 环境重新运行该测试文件,确认 test_adapter.py 全部通过(Issue 讨论中报告的本地结果为 32 passed)。同时在 POSIX 环境运行同一测试文件,确认修改后的正则仍能匹配 “not a valid URL”,没有把原有的 POSIX 覆盖放宽到失效。此外可运行 ruff check、ruff format –check 与 mypy,确认改动文件无静态检查问题。

参考来源

langchain-ai/langchain #40396

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 25440

发表回复

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