You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
stdio_client with strict decoding withholds fatal read errors until peer stdout EOF #3714
Explicit encoding_error_handler="strict" decoding of invalid UTF-8 leaves the stdio consumer waiting until the peer closes stdout.
#2454 requests changing default decoding policy. This reproduction explicitly selects strict decoding, so changing the default to replacement would leave this failure-propagation case intact. Termination should become observable without requiring peer exit.
stdout_reader() enters its finally drain before closing the read-stream writer. _drain_stdout() waits for further raw bytes under a cancellation shield. A peer retaining stdout therefore blocks both stream closure and propagation of UnicodeDecodeError.
Example Code
Self-contained failing test reusing the module's existing in-memory FakeProcess and spawn monkeypatch. A byte peer is necessary because a typed server cannot emit malformed UTF-8. Test-only branch; no production changes.
After checking out that branch:
uv run --frozen pytest tests/client/test_stdio.py::test_strict_decode_failure_reaches_consumer_before_peer_stdout_closes -q
Event barriers prove consumption of malformed bytes. After tasks settle, the consumer has not failed. Releasing EOF then surfaces UnicodeDecodeError and completes clean shutdown. The explicit delayed-error assertion fails, without a timeout.
Python & MCP Python SDK
Python 3.14.7, Linux x86_64. Latest stable 2.3.0 (2118f14f8a19bc158d8a1cf90af58d85d187f849) and main 754254c08fe1c3eda18b69da3d336106fe8d72d6: three repetitions on asyncio and Trio all fail identically. The other 35 stdio tests pass against each revision.
AI-assisted investigation and test reproduction, with a human in the loop.
Activity