-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Closed
Labels
Description
Initial Checks
- I confirm that I'm using the latest version of Pydantic AI
- I confirm that I searched for my issue in https://github.com/pydantic/pydantic-ai/issues before opening this issue
Description
unhandled errors in a TaskGroup (1 sub-exception)
+ Exception Group Traceback (most recent call last):
| File "AgentWorker.py", line 45, in run
| File "asyncio\base_events.py", line 691, in run_until_complete
| File "AgentWorker.py", line 23, in chat
| File "pydantic_ai\agent.py", line 551, in run
| async with self.iter(
| ^^^^^^^^^^
| File "contextlib.py", line 210, in __aenter__
| File "pydantic_ai\agent.py", line 777, in iter
| async with toolset:
| ^^^^^^^
| File "pydantic_ai\toolsets\combined.py", line 48, in __aenter__
| await exit_stack.enter_async_context(toolset)
| File "contextlib.py", line 659, in enter_async_context
| File "pydantic_ai\mcp.py", line 204, in __aenter__
| async with AsyncExitStack() as exit_stack:
| ^^^^^^^^^^^^^^^^
| File "contextlib.py", line 754, in __aexit__
| File "contextlib.py", line 737, in __aexit__
| File "contextlib.py", line 231, in __aexit__
| File "pydantic_ai\mcp.py", line 411, in client_streams
| async with stdio_client(server=server) as (read_stream, write_stream):
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
| File "contextlib.py", line 231, in __aexit__
| File "mcp\client\stdio\__init__.py", line 181, in stdio_client
| File "anyio\_backends\_asyncio.py", line 772, in __aexit__
| ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
+-+---------------- 1 ----------------
| Exception Group Traceback (most recent call last):
| File "mcp\client\stdio\__init__.py", line 187, in stdio_client
| File "pydantic_ai\mcp.py", line 412, in client_streams
| yield read_stream, write_stream
| File "contextlib.py", line 737, in __aexit__
| File "mcp\shared\session.py", line 218, in __aexit__
| File "anyio\_backends\_asyncio.py", line 772, in __aexit__
| ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
+-+---------------- 1 ----------------
| Traceback (most recent call last):
| File "pydantic_ai\mcp.py", line 216, in __aenter__
| await self._client.initialize()
| File "mcp\client\session.py", line 151, in initialize
| File "mcp\shared\session.py", line 286, in send_request
| mcp.shared.exceptions.McpError: Connection closed
+------------------------------------
Example Code
Python, Pydantic AI & LLM client version
from PyQt6.QtCore import QThread, pyqtSignal
from dotenv import load_dotenv
load_dotenv()
class AgentWorker(QThread):
signal_finished = pyqtSignal(str)
signal_error = pyqtSignal(str)
signal_progress = pyqtSignal(str)
signal_message_history = pyqtSignal(list)
def __init__(self, agent, user_input, message_history):
super().__init__()
self.agent = agent
self.user_input = user_input
self.message_history = message_history
self.new_message_history = []
async def chat(self):
try:
async with self.agent.run_mcp_servers():
result = await self.agent.run(
self.user_input, message_history=self.message_history
)
self.new_message_history = result.all_messages()
self.signal_message_history.emit(self.new_message_history)
self.signal_progress.emit("สำเร็จ")
if getattr(result.output, "sql", None):
self.signal_finished.emit(result.output.sql)
else:
self.signal_finished.emit(getattr(result.output, "explanation", ""))
except Exception as e:
# Re-raise so run() catches it and logs
raise
def run(self):
import traceback, logging, asyncio
loop = asyncio.new_event_loop()
loop.set_exception_handler(lambda l, c: logging.error(
f"Asyncio exception: {c.get('message')}", exc_info=c.get('exception')))
asyncio.set_event_loop(loop)
try:
loop.run_until_complete(self.chat())
except Exception as e:
self.signal_error.emit(f"{e}\n{traceback.format_exc()}")
finally:
try:
pending = asyncio.all_tasks(loop)
for task in pending:
task.cancel()
if pending:
loop.run_until_complete(asyncio.gather(*pending, return_exceptions=True))
finally:
loop.close()