Skip to content

fix(core): close session after cancelled initialization - #746

Open
hsusul wants to merge 1 commit into
googleapis:mainfrom
hsusul:fix/close-cancelled-init
Open

fix(core): close session after cancelled initialization#746
hsusul wants to merge 1 commit into
googleapis:mainfrom
hsusul:fix/close-cancelled-init

Conversation

@hsusul

@hsusul hsusul commented Jul 28, 2026

Copy link
Copy Markdown

Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly:

  • Make sure to open an issue before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea
  • Ensure the tests and linter pass
  • Communicate test infrastructure changes, i.e. API enablement, secrets (none)
  • Appropriate docs were updated (not necessary for this internal cleanup fix)

🛠️ Fixes #744

Summary

Ensure _McpHttpTransportBase.close() still closes its internally managed
aiohttp.ClientSession when the cached initialization task was cancelled.

Problem

asyncio.CancelledError inherits directly from BaseException, so the existing
except Exception around the initialization task did not handle cancellation.
Calling close() after a cancelled initialization therefore propagated
CancelledError before reaching session cleanup, leaving the managed session
open.

Minimal reproduction

  1. Create a core MCP transport that owns its aiohttp.ClientSession.
  2. Assign and cancel its cached _init_task.
  3. Await the cancelled task, then call await transport.close().

Before this change, close() raises asyncio.CancelledError and
transport._session.closed remains False. After this change, explicit cleanup
completes and the managed session is closed.

Implementation

  • Handle asyncio.CancelledError alongside ordinary initialization exceptions
    during explicit transport cleanup.
  • Add a regression test proving a cancelled initialization no longer prevents
    the managed session from closing.
  • Add adjacent coverage preserving the existing ordinary-initialization-error
    cleanup behavior.

The change does not alter initialization or request-time cancellation behavior,
and externally managed sessions remain unaffected.

Validation

  • python -m pytest tests/mcp_transport/test_base.py::TestMcpHttpTransportBase::test_close_managed_session_after_cancelled_initialization -v
    • Before the fix: failed from transport.close() with
      asyncio.exceptions.CancelledError.
    • After the fix: 1 passed.
  • Test sensitivity: temporarily reverting only the production clause made the
    regression fail again; restoring it made the test pass.
  • python -m pytest tests/mcp_transport/test_base.py -q39 passed.
  • python -m pytest tests -q --ignore=tests/test_e2e.py --ignore=tests/test_sync_e2e.py --ignore=tests/test_e2e_mcp.py --ignore=tests/conformance --cov=src/toolbox_core --cov-report=term --cov-fail-under=90
    482 passed, total coverage 91.80%.
  • python -m pytest tests/unit -q in toolbox-adk59 passed.
  • python -m pytest tests -k 'not e2e' -q in toolbox-langchain
    60 passed, 64 deselected.
  • python -m pytest tests -k 'not e2e' -q in toolbox-llamaindex
    61 passed, 64 deselected.
  • black --check . — passed; 44 files would be left unchanged.
  • isort --check . — passed.
  • MYPYPATH='./src' mypy --install-types --non-interactive --cache-dir=<temporary-cache> -p toolbox_core
    Success: no issues found in 29 source files.
  • git diff upstream/main...HEAD --check — passed.

Live E2E and conformance suites were not run locally because they require
external Toolbox/GCP infrastructure. Fork CI remains subject to the
repository's maintainer-triggered workflow.

Compatibility and risk

The runtime change is limited to explicit cleanup after an initialization task
has already been cancelled. Ordinary initialization errors, successful
initialization, and unmanaged-session cleanup retain their existing behavior.

Non-goals and related work

AI assistance

AI assistance was used for repository inspection, implementation, testing, and
drafting this pull request. The contributor reviewed the final diff and
validation evidence.

@hsusul
hsusul requested a review from a team as a code owner July 28, 2026 15:27
@anubhav756 anubhav756 added the priority: p1 Important issue which blocks shipping the next release. Will be fixed prior to next release. label Aug 11, 2026
@anubhav756

Copy link
Copy Markdown
Contributor

/gcbrun

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority: p1 Important issue which blocks shipping the next release. Will be fixed prior to next release.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(core): close managed session after cancelled initialization

3 participants