PrefectHQ/fastmcp · error · RuntimeError
Session task completed without exception but connection fail
Error message
Session task completed without exception but connection failed
What it means
After spawning the background session task, the client waits briefly for it to fail or become ready. If the task finishes without raising but the connection still isn't established, `_connect` raises this RuntimeError, since a completed session task with no exception implies the connection sequence failed silently. It is an internal invariant check.
Source
Thrown at fastmcp_slim/fastmcp/client/client.py:1040
f"Error closing transport after cancellation: {e}"
)
raise
session_task = self._session_state.session_task
if not session_task.done() and self._session_state.session is None:
# `_session_runner` sets `ready_event` from its `finally`,
# so a failed connect can wake the wait above before the
# task is marked done. No session means the connect failed,
# so let the task settle and report the failure here rather
# than letting the raw transport error escape on the next
# request.
await asyncio.wait([session_task], timeout=3)
if session_task.done():
exception = session_task.exception()
if exception is None:
raise RuntimeError(
"Session task completed without exception but connection failed"
)
failure = _connection_failure(exception)
if failure is exception:
raise exception
raise failure from exception
self._session_state.nesting_counter += 1
return self
async def _disconnect(self, force: bool = False):
"""
Disconnect from session using reference counting.
This method implements proper cleanup for reentrant context managers:
- Decrements reference counter for normal exits
- Only stops session when counter reaches 0 (no more active contexts)View on GitHub (pinned to 1f02114297)
Solutions
- Check that the server process/endpoint stays alive after startup (it may be exiting cleanly too early)
- Inspect server startup logs and exit code for silent early exits
- Update fastmcp and the MCP SDK — this usually indicates a transport/session bug
- Test with a different transport to isolate the fault
Defensive patterns
Strategy: try-catch
Validate before calling
proc = await anyio.open_process([cmd])
await anyio.sleep(1)
if proc.returncode is not None:
raise RuntimeError(f"server exited early with code {proc.returncode}") Try / catch
try:
async with client:
...
except RuntimeError as e:
if "without exception but connection failed" in str(e):
logger.error("silent transport startup failure; check server exit behavior")
raise Prevention
- Ensure the server process does not exit cleanly before serving
- Keep fastmcp and mcp SDK versions current
- Test transports in isolation to catch silent early exits
When it happens
Trigger: The session coroutine completes normally before signaling a ready connection — e.g. the transport exits early without error, or closes streams gracefully during startup.
Common situations: A stdio server exiting cleanly (code 0) immediately on startup without serving; a transport that closes its streams during initialization; races between session readiness and task completion.
Related errors
- Server session was closed unexpectedly
- Both 'httpx_client_factory' and 'verify' were provided. The
- Both 'httpx_client_factory' and 'verify' were provided. The
- module {__name__!r} has no attribute {name!r}
- Cannot resolve tool reference: {fn!r}
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/9892e681064c4d11.
Report an issue: GitHub.