Skip to content

fix: handle ClosedResourceError when logging errors to disconnected clients#2170

Open
giulio-leone wants to merge 1 commit intomodelcontextprotocol:mainfrom
giulio-leone:fix/client-disconnect-closed-resource-2064
Open

fix: handle ClosedResourceError when logging errors to disconnected clients#2170
giulio-leone wants to merge 1 commit intomodelcontextprotocol:mainfrom
giulio-leone:fix/client-disconnect-closed-resource-2064

Conversation

@giulio-leone
Copy link

Summary

Fixes #2064

When a client disconnects while a stateless streamable-HTTP server is processing a request, the exception handler in _handle_message tries to send_log_message() back to the client. Since the session's write stream is already closed, this raises ClosedResourceError, which is unhandled and crashes the session with an ExceptionGroup.

Root Cause

_handle_message (lowlevel/server.py) has an Exception case that:

  1. Logs the error ✅
  2. Tries session.send_log_message() to notify the client ❌ — crashes if the client is gone

Fix

Wrap the send_log_message() call with a try/except for anyio.ClosedResourceError and anyio.BrokenResourceError. When the write stream is closed (client disconnected), the error is silently discarded with a debug log.

Tests

All 475 server tests pass (2 consecutive clean runs). ruff check and ruff format clean.

…lients

Wrap send_log_message() in _handle_message's exception handler with a
try/except for ClosedResourceError and BrokenResourceError. When a client
disconnects during request processing, the server catches the stream
exception but then crashes trying to send the error log back through the
already-closed write stream.

Closes modelcontextprotocol#2064

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

ClientDisconnect during _handle_post_request crashes stateless session with ClosedResourceError

1 participant