Skip to content

Comments

Fix event loop closed warning during stdio cleanup#2805

Draft
jlowin wants to merge 2 commits intomainfrom
fix-stdio-cleanup-warning
Draft

Fix event loop closed warning during stdio cleanup#2805
jlowin wants to merge 2 commits intomainfrom
fix-stdio-cleanup-warning

Conversation

@jlowin
Copy link
Member

@jlowin jlowin commented Jan 7, 2026

When using Client with stdio transport in pytest, an "Event loop is closed" warning can appear during test teardown on Linux CI. This happens because asyncio's BaseSubprocessTransport.__del__ gets triggered by GC after pytest-asyncio closes the event loop.

This PR attempts to fix the issue by forcing GC and yielding to the event loop after the stdio_client context manager exits but while the loop is still running. This should allow any subprocess transport cleanup callbacks to execute before the loop closes.

# After stdio_client context exits, force garbage collection while the
# event loop is still running.
gc.collect()
await asyncio.sleep(0)

Note: This fix may not fully resolve the issue - it needs to be tested in CI on Linux. The warning is fundamentally a race between GC and event loop closure, so there may still be edge cases. If this doesn't work, we may need to either:

  1. Make the fix more aggressive (multiple GC cycles, longer delay)
  2. Suppress the warning in pytest configuration
  3. Report upstream to the MCP SDK or Python

Closes #2792


Tests added:

  • tests/client/test_stdio_cleanup.py - Tests that convert PytestUnraisableExceptionWarning to errors to catch the issue

Add GC call and yield after stdio_client context exits to clean up
asyncio subprocess transport references while the loop is still running.
@marvin-context-protocol marvin-context-protocol bot added bug Something isn't working. Reports of errors, unexpected behavior, or broken functionality. client Related to the FastMCP client SDK or client-side functionality. tests labels Jan 7, 2026
Add pytest filterwarnings to catch unawaited coroutine warnings as
errors. Fix the underlying issue in _await_with_session_monitoring
where a coroutine was not closed before raising when session task
was already done.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working. Reports of errors, unexpected behavior, or broken functionality. client Related to the FastMCP client SDK or client-side functionality. tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RuntimeError: Event loop is closed warning during subprocess transport cleanup in pytest

1 participant