Skip to content

Conversation

@kxbnb
Copy link

@kxbnb kxbnb commented Feb 10, 2026

Summary

  • When an SSE stream closes without sending any events with IDs, _handle_sse_response previously returned silently, leaving send_request hanging forever
  • Now sends a JSONRPCError with CONNECTION_CLOSED to the read stream writer so the pending request fails with a clear error instead of hanging indefinitely
  • Adds regression test that mocks an empty SSE response and verifies the error is sent

Fixes #1811

Reproduction

When a server closes the SSE stream before sending any events (e.g., server crash, network interruption before first event), _handle_sse_response falls through to the reconnection check. With last_event_id still None, the function silently returns. The caller (send_request) is left waiting on response_stream_reader.receive() which never resolves.

Test plan

  • New test test_handle_sse_response_sends_error_when_stream_closes_without_event_id — mocks an SSE response with zero events, verifies CONNECTION_CLOSED error is sent to the read stream writer
  • All 50 existing test_streamable_http.py tests pass
  • pyright clean (0 errors)

🤖 Generated with Claude Code

…t ID

When an SSE stream closes without sending any events with IDs,
_handle_sse_response silently returns instead of notifying the session.
This leaves send_request waiting forever on a response that will never
arrive.

Send a JSONRPCError with CONNECTION_CLOSED to the read stream writer
so the pending request fails with a clear error instead of hanging.

Fixes modelcontextprotocol#1811

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@kxbnb kxbnb force-pushed the fix/sse-stream-closed-no-event-id branch from 5228e78 to 033dba3 Compare February 10, 2026 19:42
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.

client's read_stream_writer open after SSE disconnection hanging .receive()

1 participant