From afbe68eebc84d1959215e1cc5c300f585c4073b5 Mon Sep 17 00:00:00 2001 From: webtecnica <75556242+webtecnica@users.noreply.github.com> Date: Tue, 7 Jul 2026 09:08:10 -0300 Subject: [PATCH] fix(mcp): move t.cancel() inside try block to prevent RuntimeError on /exit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During shutdown, the event loop is closed before MCP tasks finish, so t.cancel() → call_soon() raises RuntimeError('Event loop is closed'). Moved t.cancel() inside the try block at both locations (keepalive loop and _wait_for_reconnect_or_shutdown). Closes #60197 (cherry picked from commit 8c7afb4aa6e552e055868484ea3effdd3fdae0c4) Co-authored-by: AIalliAI <285906080+AIalliAI@users.noreply.github.com> --- tools/mcp_tool.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tools/mcp_tool.py b/tools/mcp_tool.py index 56dd228ca44a..8cd4d5de1ac7 100644 --- a/tools/mcp_tool.py +++ b/tools/mcp_tool.py @@ -1761,10 +1761,12 @@ async def _wait_for_lifecycle_event(self) -> str: finally: for t in (shutdown_task, reconnect_task): if not t.done(): - t.cancel() try: + t.cancel() await t - except (asyncio.CancelledError, Exception): + except (asyncio.CancelledError, RuntimeError): + pass + except Exception: pass if self._shutdown_event.is_set(): @@ -1797,10 +1799,12 @@ async def _wait_for_reconnect_or_shutdown(self) -> str: finally: for t in (shutdown_task, reconnect_task): if not t.done(): - t.cancel() try: + t.cancel() await t - except (asyncio.CancelledError, Exception): + except (asyncio.CancelledError, RuntimeError): + pass + except Exception: pass if self._shutdown_event.is_set(): return "shutdown"