
BrokenResourceError race condition in stdio_client cleanup when context exits quickly
快速结论:该报错发生在使用 MCP Python SDK 的 stdio_client 异步上下文管理器时,当调用代码在子进程完成输出前快速退出,导致后台任务(stdout_reader)与清理代码(finally 块之间发生竞态条件。优先排查是否在退出 context 前取消了任务组的 scope。
问题场景
用户运行 MCP(Model Context Protocol)Python SDK 的 stdio_client 工具时,当客户端快速退出 context(例如用户断开连接),子进程尚未完成数据输出(如初始化消息),导致 BrokenResourceError 异常。该问题在 modelcontextprotocol/python-sdk 仓库的 main 分支(commit b33c811)上可稳定复现。
报错原文
ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
+-+---------------- 1 ----------------
| Traceback (most recent call last):
| File "mcp/client/stdio/__init__.py", line 162, in stdout_reader
| await read_stream_writer.send(session_message)
| File "anyio/streams/memory.py", line 242, in send
| self.send_nowait(item)
| File "anyio/streams/memory.py", line 213, in send_nowait
| raise BrokenResourceError
| anyio.BrokenResourceError
+------------------------------------
原因分析
竞态条件导致的问题:
stdio_client生成子进程后,stdout_reader任务在 task group 中运行,调用await read_stream_writer.send(session_message)从子进程 stdout 读取数据并发送。- 调用代码退出 context 后,
finally块执行,先终止子进程,然后关闭read_stream_writer(send 端)和read_stream(receive 端)。 - 此时
stdout_reader任务可能仍阻塞在send()调用上,而 receive 端刚刚被关闭,anyio 抛出BrokenResourceError(不同于ClosedResourceError,后者是调用者自己关闭了 send 端)。 - 现有的
except只捕获ClosedResourceError,不捕获BrokenResourceError,导致异常冒泡到ExceptionGroup。
环境排查
- Python 版本:3.12.1(测试环境)
- MCP Python SDK 版本:当前 main 分支(b33c811)
- anyio 版本:从 pip 安装的最新版本
- 操作系统:Linux
- 确认是否使用了 uv 或 pip 管理依赖
解决步骤
- 第一步:在
finally块中优先取消 task group scope
在关闭流之前,添加tg.cancel_scope.cancel(),确保后台任务收到取消信号后停止阻塞。
修改位置:src/mcp/client/stdio/__init__.py的finally块顶部。 - 第二步:在
stdout_reader和stdin_writer中同时捕获BrokenResourceError和ClosedResourceError
作为防御性编程,在异常处理中增加anyio.BrokenResourceError,确保即使存在极窄的时间窗口也能安全退出。 - 可优先尝试: 如果无法修改 SDK 代码,可参考 Issue 中的 workaround——使用
asyncio.Lock序列化 MCP 生命周期操作,避免 enter/exit 操作重叠触发竞态条件。
注意: 以上两步修复必须同时应用。仅取消 scope 可能仍有理论窗口,仅捕获异常则未解决根本的排序问题。
验证方法
使用 Issue 中提供的单文件复现脚本:
python3 -m uv run python repro_1960.py
应用修复后,脚本应无异常退出。若之前能稳定复现 BrokenResourceError,修复后应不再抛出。也可参考 PR #2219 的测试用例。

![[BUG]: Desktop Assistant "Attach application" produces low-resolution screenshots on Windows 11 (1.14.0)](https://www.chat-gpts.plus/wp-content/uploads/2026/06/5829-2265d5de-768x403.jpg)
![[BUG]: Gmail agent API key bug/parser](https://www.chat-gpts.plus/wp-content/uploads/2026/06/5832-72c9ff2a-768x403.jpg)
