microsoft/semantic-kernel · error · FunctionExecutionException
Failed to enter context manager.
Error message
Failed to enter context manager.
What it means
Thrown by MCPPluginBase.connect (mcp.py:308) as a FunctionExecutionException, wrapping any exception during connect() that is NOT a KernelPluginInvalidConfigurationError. The connect() flow spawns _inner_connect as a task and waits on a ready_event; only config errors are re-raised verbatim, everything else (and event-wait failures) is wrapped here and forces a close().
Source
Thrown at python/semantic_kernel/connectors/mcp.py:308
async def __aexit__(
self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: Any
) -> None:
"""Exit the context manager."""
await self.close()
async def connect(self) -> None:
"""Connect to the MCP server."""
ready_event = asyncio.Event()
try:
self._current_task = asyncio.create_task(self._inner_connect(ready_event))
await ready_event.wait()
except KernelPluginInvalidConfigurationError:
ready_event.clear()
raise
except Exception as ex:
ready_event.clear()
await self.close()
raise FunctionExecutionException("Failed to enter context manager.") from ex
async def close(self) -> None:
"""Disconnect from the MCP server."""
if self._stop_event:
# Signal the stop event, which asks the _inner_connect
# method to close the session with the exit stack
self._stop_event.set()
if self._current_task:
# After, the signal, we wait for it to close the exit stack.
await self._current_task
self._current_task = None
self.session = None
async def _inner_connect(self, ready_event: asyncio.Event) -> None:
if not self.session:
try:
transport = await self._exit_stack.enter_async_context(self.get_mcp_client())
except Exception as ex:View on GitHub (pinned to c028a0c7dc)
Solutions
- Inspect the chained __cause__ (from ex) for the real underlying error before acting.
- Ensure connect() is called exactly once and awaited fully; use the async context manager (async with plugin:) to avoid races.
- If load_tools/load_prompts is the culprit, set load_tools=False/load_prompts=False and load manually after connect.
- Avoid cancelling the connect task; if you must, expect this wrapper.
Example fix
# before
await plugin.connect() # may race if called twice
# after (use the context manager)
async with plugin:
result = await plugin.call_tool("foo", arg=1) Defensive patterns
Strategy: try-catch
Validate before calling
# ensure single, awaited connect before use
async def safe_connect(plugin) -> bool:
if plugin.session is not None:
return True
await plugin.connect()
return plugin.session is not None Type guard
def plugin_is_connected(plugin) -> bool:
return getattr(plugin, "session", None) is not None Try / catch
from semantic_kernel.exceptions.function_exceptions import FunctionExecutionException
try:
async with plugin:
await plugin.call_tool("foo")
except FunctionExecutionException as ex:
if "Failed to enter context manager" in str(ex):
# inspect ex.__cause__; likely asyncio cancellation or a runtime error
log.error("connect failed: %r", ex.__cause__) Prevention
- Use the async context manager (async with plugin:) so connect/close are deterministic.
- Never call connect() concurrently from two coroutines on the same plugin.
- Do not cancel the connect task mid-handshake.
- If load_tools/load_prompts errors during connect, disable them and load manually.
When it happens
Trigger: An asyncio.CancelledError or unexpected runtime error during ready_event.wait(); a failure inside _inner_connect that surfaces as a generic Exception rather than the dedicated config errors at mcp.py:329/345/352; double-connect races; the task being cancelled externally.
Common situations: Calling connect() concurrently from two coroutines; cancelling the connect task mid-handshake; an unhandled error in load_tools()/load_prompts() (which run after session init inside _inner_connect); event-loop closure during connect.
Related errors
- Failed to connect to the MCP server. Please check your confi
- Failed to create a session. Please check your configuration.
- Failed to initialize session. Please check your configuratio
- Failed to call tool '{tool_name}'.
- Failed to call prompt '{prompt_name}'.
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/ff57e8b9bc9200f8.
Report an issue: GitHub.