Skip to content

fix(streamable-http): wait for post_writer before yielding#2666

Open
Epochex wants to merge 3 commits into
modelcontextprotocol:mainfrom
Epochex:fix/1675-streamable-http-race
Open

fix(streamable-http): wait for post_writer before yielding#2666
Epochex wants to merge 3 commits into
modelcontextprotocol:mainfrom
Epochex:fix/1675-streamable-http-race

Conversation

@Epochex
Copy link
Copy Markdown

@Epochex Epochex commented May 23, 2026

Fixes #1675.

What happened

streamable_http_client() started StreamableHTTPTransport.post_writer() with tg.start_soon(), then yielded (read_stream, write_stream) immediately.

Because the write side is a zero-buffer in-memory stream, there is a narrow startup window where the first requests right after initialize() can race with the writer task entering its stream contexts. That shows up as flaky/incorrect behavior on the first few calls (e.g. list_tools()).

What changed

  • Start post_writer() with await tg.start(...) and have post_writer() signal readiness via TaskStatus.started(None).
  • Add regression tests that open short-lived sessions and issue consecutive requests immediately after initialize().

Extra hardening

While iterating on the Windows lowest-direct matrix, one job surfaced an unclosed pipe transport warning during teardown. I added an explicit process.stdout.aclose() in stdio_client() teardown to make subprocess cleanup more robust.

Tests

  • uv run --frozen pytest tests/shared/test_streamable_http.py -k 'no_race_on_consecutive_requests or rapid_request_sequence'
  • uv run --frozen ruff check src/mcp/client/streamable_http.py tests/shared/test_streamable_http.py
  • uv run --frozen pyright src/mcp/client/streamable_http.py
  • uv run --frozen pytest tests/issues/test_1027_win_unreachable_cleanup.py tests/issues/test_129_resource_templates.py

@Epochex
Copy link
Copy Markdown
Author

Epochex commented May 23, 2026

Hi @maxisbey — this fixes #1675 (StreamableHTTP startup race right after initialize). It waits for post_writer readiness before yielding streams and adds regression tests. I also tightened stdio teardown by closing stdout to avoid an unclosed pipe transport warning on Windows.

Local tests are listed in the PR body. Would appreciate a review when you have a moment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Streamable HTTP transport drops requests immediately after initialize

1 participant