Skip to content

Forced POSIX relay: asyncio's child watcher can warn into the stdio server's stderr #472

Closed

Description

@hellices

Problem

tests/mcp/test_stdio.py::test_stdout_noise_is_diverted_and_wire_is_restored[True] failed on test (3.12) in #469's CI (run 39933615395):

assert sorted(err.decode().splitlines()) == ["fd-handler-noise", "python-handler-noise"]
+ 'child process pid 3098 exit status already read:  will report returncode 255'

err is the stdio server's own stderr. The extra line comes from the server's asyncio child watcher, not from the test process.

Cause

relay=True makes the stdio server run the Windows-only relays (_relay_stdin, _relay_stdout) on POSIX. When the test closes the server's stdin, the stdin relay child exits on its own. If _relay_stdin's cleanup runs before the event loop has processed that exit, process.returncode is still None, so the cleanup calls process.kill(). Popen.send_signal polls the child first (bpo-38630), and on POSIX that waitpid reaps it. The loop's child watcher then finds the child gone, reports exit status 255, and logs the warning above.

Production runs the relays only on Windows, where nothing reaps children, so the race exists only where the tests force the relays onto POSIX. Three forced-relay tests compare the server's stderr exactly (test_stdio.py lines 575, 624 and 875), and any of them can fail this way. It is rare: it had not appeared in the previous 40 failed CI runs.

Done when

  • The exact stderr checks drop asyncio's child-watcher race warnings and nothing else. Both forms count: the pidfd watcher's "exit status already read" and the threaded watcher's "Unknown child process pid".
  • A test pins that the filter removes those lines and keeps every other line.

Activity

  1. added this to the v0.7.0 milestone on Oct 23, 2026
  2. self-assigned this
    on Oct 23, 2026
  3. added
    bugSomething isn't working
    area: mcpModel Context Protocol server and external host integration
    concern: testingTest infrastructure, evaluation, and quality measurement
    status: acceptedConfirmed bug or accepted change; a pull request may follow once the issue is assigned
    on Oct 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area: mcpModel Context Protocol server and external host integrationbugSomething isn't workingconcern: testingTest infrastructure, evaluation, and quality measurementstatus: acceptedConfirmed bug or accepted change; a pull request may follow once the issue is assigned

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions