Commit 4b0e3e8
roman groblicki
fix(client/stdio): fall back to os.devnull when sys.stderr is None
Under pythonw.exe on Windows (desktop shortcuts, silent .bat launches,
anything without a console attached), sys.stderr is None. The previous
default `errlog: TextIO = sys.stderr` then propagated that None handle
into the subprocess as its stderr.
asyncio's Windows ProactorEventLoop subprocess transport mishandles a
None stderr handle, corrupting IOCP routing on the read pump. The
symptom is `ClosedResourceError` on the first real RPC after
`initialize()` succeeds. Bursty servers like
`@modelcontextprotocol/server-filesystem` (whose initialize → list_tools
traffic happens within milliseconds) hit this consistently; quieter
servers like Gmail clients usually slip through. Reproducing requires
launching a stdio MCP client via pythonw.exe with no stderr redirect —
running the same code from a console (python.exe) or with stderr
redirected to a file works because sys.stderr is then a real handle.
Fix: change `errlog: TextIO = sys.stderr` to `errlog: TextIO | None =
None` and resolve at call time. Falls back to `sys.stderr` when it is
a real handle, `os.devnull` otherwise. Backward compatible — callers
passing an explicit `errlog` keep the same behavior.
Also applied the same fallback in `_create_platform_compatible_process`
as defense in depth, so any internal caller that omits `errlog` is
safe regardless of whether `sys.stderr` is None.
Verified by reproducing the bug under pythonw.exe (filesystem-server
list_tools fails with ClosedResourceError) and confirming the fix
restores it to working state without changing behavior under
python.exe or with explicit errlog.1 parent 3d7b311 commit 4b0e3e8
1 file changed
Lines changed: 23 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
102 | 102 | | |
103 | 103 | | |
104 | 104 | | |
105 | | - | |
| 105 | + | |
106 | 106 | | |
107 | 107 | | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
108 | 119 | | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
109 | 123 | | |
110 | 124 | | |
111 | 125 | | |
| |||
230 | 244 | | |
231 | 245 | | |
232 | 246 | | |
233 | | - | |
| 247 | + | |
234 | 248 | | |
235 | 249 | | |
236 | 250 | | |
237 | 251 | | |
238 | 252 | | |
239 | 253 | | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
240 | 259 | | |
| 260 | + | |
| 261 | + | |
241 | 262 | | |
242 | 263 | | |
243 | 264 | | |
| |||
0 commit comments