{"record":{"id":"9892e681064c4d11","repo":"PrefectHQ/fastmcp","slug":"session-task-completed-without-exception-but-conne","errorCode":null,"errorMessage":"Session task completed without exception but connection failed","messagePattern":"Session task completed without exception but connection failed","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/client/client.py","lineNumber":1040,"sourceCode":"                                    f\"Error closing transport after cancellation: {e}\"\n                                )\n\n                    raise\n\n                session_task = self._session_state.session_task\n                if not session_task.done() and self._session_state.session is None:\n                    # `_session_runner` sets `ready_event` from its `finally`,\n                    # so a failed connect can wake the wait above before the\n                    # task is marked done. No session means the connect failed,\n                    # so let the task settle and report the failure here rather\n                    # than letting the raw transport error escape on the next\n                    # request.\n                    await asyncio.wait([session_task], timeout=3)\n\n                if session_task.done():\n                    exception = session_task.exception()\n                    if exception is None:\n                        raise RuntimeError(\n                            \"Session task completed without exception but connection failed\"\n                        )\n                    failure = _connection_failure(exception)\n                    if failure is exception:\n                        raise exception\n                    raise failure from exception\n\n            self._session_state.nesting_counter += 1\n\n        return self\n\n    async def _disconnect(self, force: bool = False):\n        \"\"\"\n        Disconnect from session using reference counting.\n\n        This method implements proper cleanup for reentrant context managers:\n        - Decrements reference counter for normal exits\n        - Only stops session when counter reaches 0 (no more active contexts)","sourceCodeStart":1022,"sourceCodeEnd":1058,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/client/client.py#L1022-L1058","documentation":"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.","triggerScenarios":"The session coroutine completes normally before signaling a ready connection — e.g. the transport exits early without error, or closes streams gracefully during startup.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"proc = await anyio.open_process([cmd])\nawait anyio.sleep(1)\nif proc.returncode is not None:\n    raise RuntimeError(f\"server exited early with code {proc.returncode}\")","typeGuard":null,"tryCatchPattern":"try:\n    async with client:\n        ...\nexcept RuntimeError as e:\n    if \"without exception but connection failed\" in str(e):\n        logger.error(\"silent transport startup failure; check server exit behavior\")\n    raise","preventionTips":["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"],"tags":["python","transport","startup","race-condition"],"backgroundTag":"connection-startup-failed","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}