{"record":{"id":"a33cbd1eb6b61b69","repo":"agentscope-ai/agentscope","slug":"one-or-more-tool-calls-raised-an-exception","errorCode":null,"errorMessage":"One or more tool calls raised an exception","messagePattern":"One or more tool calls raised an exception","errorType":"exception","errorClass":"ExceptionGroup","httpStatus":null,"severity":"error","filePath":"src/agentscope/agent/_agent.py","lineNumber":2120,"sourceCode":"                    event = queue.get_nowait()\n                except asyncio.QueueEmpty:\n                    break\n                if event is sentinel:\n                    continue\n                yield event\n            # Consume the cancel so this generator returns normally. The\n            # caller relies on the flushed ``ToolResultEndEvent(state=\n            # INTERRUPTED)`` events, not on the exception, to detect the\n            # interruption — mirroring the event-based propagation used by\n            # :meth:`_execute_sequential_tool_calls`.\n            asyncio.current_task().uncancel()\n            return\n\n        # All tasks are done at this point; collect and re-raise exceptions.\n        results = await gather_task\n        exceptions = [r for r in results if isinstance(r, Exception)]\n        if exceptions:\n            raise ExceptionGroup(\n                \"One or more tool calls raised an exception\",\n                exceptions,\n            )\n\n    async def _into_queue(\n        self,\n        tool_call: ToolCallBlock,\n        queue: Queue,\n        kept_rules: list[PermissionRule] | None = None,\n    ) -> None:\n        \"\"\"Execute a single tool call and forward every event into *queue*.\n\n        Args:\n            tool_call (`ToolCallBlock`):\n                The tool call to execute.\n            queue (`Queue`):\n                The shared async queue that collects events from all\n                concurrent workers.","sourceCodeStart":2102,"sourceCodeEnd":2138,"githubUrl":"https://github.com/agentscope-ai/agentscope/blob/e90f1c7592896cc95f6e5ee506194f533378247d/src/agentscope/agent/_agent.py#L2102-L2138","documentation":"Raised as an ExceptionGroup when one or more concurrently executing tool call tasks raised an exception. The agent runs tool calls in parallel (e.g. via parallel tool execution mode); after all tasks finish, any exceptions collected are bundled and re-raised together so no failure is silently dropped.","triggerScenarios":"Agent configured with concurrent/parallel tool execution and multiple tool calls in one reply block where at least one tool raises (e.g. a tool function throws, a tool's internal API call fails, or input processing fails inside the task).","commonSituations":"Custom tools that perform network or file I/O failing intermittently under concurrency; a buggy third-party tool raising on edge-case inputs; tools with unvalidated assumptions running in parallel mode.","solutions":["Inspect exc.exceptions (the ExceptionGroup members) to find which tool actually failed and why","Wrap individual tool functions so they return error results instead of raising, letting the agent see tool errors as observations","Fix the root-cause exception in the failing tool (check its stack trace inside the group)","Switch to sequential tool execution if partial failures should abort cleanly"],"exampleFix":"// before\ndef my_tool(path: str) -> str:\n    with open(path) as f:  # raises, bubbles into ExceptionGroup\n        return f.read()\n\n// after\ndef my_tool(path: str) -> str:\n    try:\n        with open(path) as f:\n            return f.read()\n    except OSError as e:\n        return f\"Error reading {path}: {e}\"  # returned as tool result","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"def is_tool_exception_group(exc: BaseException) -> bool:\n    return isinstance(exc, ExceptionGroup) and any(\n        isinstance(e, Exception) for e in exc.exceptions\n    )","tryCatchPattern":"try:\n    reply = await agent.run(msg)\nexcept ExceptionGroup as eg:\n    for sub in eg.exceptions:\n        logger.error(\"tool call failed: %r\", sub)","preventionTips":["Make tool functions return error strings instead of raising","Wrap risky I/O inside tool implementations with try/except","Test each tool standalone before enabling parallel execution"],"tags":["agentscope","tool-calls","concurrency","exception-group"],"backgroundTag":"concurrent-task-exception-group","analyzedSha":"e90f1c7592896cc95f6e5ee506194f533378247d","analyzedAt":"2026-08-28T18:24:12.087Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}