diff --git a/src/mcp/shared/session.py b/src/mcp/shared/session.py index 243eef5ae..c89626750 100644 --- a/src/mcp/shared/session.py +++ b/src/mcp/shared/session.py @@ -428,6 +428,24 @@ async def _handle_session_message(message: SessionMessage) -> None: async for message in self._read_stream: if isinstance(message, Exception): await self._handle_incoming(message) + + # Fix #1401: Propagate exception to all pending requests + # This prevents waiters from hanging when the transport fails + error_data = ( + message.to_error_data() + if isinstance(message, MCPError) + else ErrorData(code=0, message=str(message)) + ) + + # We must send an error to every individual waiter + for req_id, stream in list(self._response_streams.items()): + try: + # Send a response with the correct ID + await stream.send(JSONRPCError(jsonrpc="2.0", id=req_id, error=error_data)) + finally: + # Ensure we clean up the stream so finally block doesn't double-handle + self._response_streams.pop(req_id, None) + await stream.aclose() continue await _handle_session_message(message)