Skip to content

[fix] catch CancelledError in MCP reconnection and remove redundant build_tools#6631

Open
hztBUAA wants to merge 5 commits intoagno-agi:mainfrom
hztBUAA:fix/mcp-reconnection-cancelled-error
Open

[fix] catch CancelledError in MCP reconnection and remove redundant build_tools#6631
hztBUAA wants to merge 5 commits intoagno-agi:mainfrom
hztBUAA:fix/mcp-reconnection-cancelled-error

Conversation

@hztBUAA
Copy link
Contributor

@hztBUAA hztBUAA commented Feb 19, 2026

Summary

Fixes asyncio.CancelledError being silently swallowed during MCP reconnection, and removes redundant build_tools calls after forced reconnection.

Fixes #6235

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Checklist

  • Code complies with style guidelines
  • Ran ./scripts/format.sh and ./scripts/validate.sh
  • Self-review completed
  • Tests added/updated (13 new tests)

Additional Notes

Root cause: Broad except (RuntimeError, BaseException) handlers in MCPTools swallowed asyncio.CancelledError, preventing proper task cancellation. Additionally, refresh_connection called connect(force=True) (which runs build_tools internally) followed by another explicit build_tools().

Fix: Added explicit CancelledError re-raise before broad handlers in MCPTools/MultiMCPTools. Restructured refresh logic to skip redundant build_tools after reconnection.

…ild_tools

When an MCP server disconnects and reconnection is attempted, asyncio.CancelledError
was being silently swallowed by broad BaseException catches, preventing proper task
cancellation propagation. Additionally, build_tools was called redundantly during
reconnection since connect(force=True) already calls initialize() -> build_tools()
internally.

Changes:
- Add explicit asyncio.CancelledError handling in MCPTools.connect(), build_tools(),
  and initialize() to re-raise instead of swallowing
- Add same CancelledError handling in MultiMCPTools.connect() and __aenter__()
- Restructure refresh_connection logic in agent/_tools.py and team/_tools.py to
  only call build_tools() when connection is alive (avoiding duplicate call after
  reconnection)
- Add asyncio.CancelledError re-raise in the refresh connection exception handlers
@hztBUAA hztBUAA requested a review from a team as a code owner February 19, 2026 21:03
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 35aba6d6c0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 242 to 245
if not is_alive:
# connect(force=True) internally calls initialize() -> build_tools(),
# so no separate build_tools() call is needed after reconnection.
await tool.connect(force=True) # type: ignore

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid appending stale MCP tools after failed reconnect

In this if not is_alive branch, connect(force=True) is now the only refresh step, but MCPTools.connect() swallows non-cancellation connection failures and returns without raising, so execution falls through to tool inclusion when check_mcp_tools=False. That flag is used by schema endpoints (e.g. os/routers/agents/schema.py), so a dead MCP server can now leave a stale toolkit (with old functions) in the returned tool list instead of being skipped as before when the post-connect build_tools() failure triggered continue.

Useful? React with 👍 / 👎.

uzaxirr and others added 2 commits March 2, 2026 19:24
…ools

Without this guard, a task cancellation during send_ping() would be
caught by the broad `except BaseException` handler, returning False
instead of propagating the cancellation signal.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.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.

[Bug] MCP Reconnection propagates CancelledError stopping Agent execution & Redundant build_tools call

3 participants