agentscope-ai/agentscope · error · ExceptionGroup

One or more tool calls raised an exception

Error message

One or more tool calls raised an exception

What it means

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.

Source

Thrown at src/agentscope/agent/_agent.py:2120

                    event = queue.get_nowait()
                except asyncio.QueueEmpty:
                    break
                if event is sentinel:
                    continue
                yield event
            # Consume the cancel so this generator returns normally. The
            # caller relies on the flushed ``ToolResultEndEvent(state=
            # INTERRUPTED)`` events, not on the exception, to detect the
            # interruption — mirroring the event-based propagation used by
            # :meth:`_execute_sequential_tool_calls`.
            asyncio.current_task().uncancel()
            return

        # All tasks are done at this point; collect and re-raise exceptions.
        results = await gather_task
        exceptions = [r for r in results if isinstance(r, Exception)]
        if exceptions:
            raise ExceptionGroup(
                "One or more tool calls raised an exception",
                exceptions,
            )

    async def _into_queue(
        self,
        tool_call: ToolCallBlock,
        queue: Queue,
        kept_rules: list[PermissionRule] | None = None,
    ) -> None:
        """Execute a single tool call and forward every event into *queue*.

        Args:
            tool_call (`ToolCallBlock`):
                The tool call to execute.
            queue (`Queue`):
                The shared async queue that collects events from all
                concurrent workers.

View on GitHub (pinned to e90f1c7592)

Solutions

  1. Inspect exc.exceptions (the ExceptionGroup members) to find which tool actually failed and why
  2. Wrap individual tool functions so they return error results instead of raising, letting the agent see tool errors as observations
  3. Fix the root-cause exception in the failing tool (check its stack trace inside the group)
  4. Switch to sequential tool execution if partial failures should abort cleanly

Example fix

// before
def my_tool(path: str) -> str:
    with open(path) as f:  # raises, bubbles into ExceptionGroup
        return f.read()

// after
def my_tool(path: str) -> str:
    try:
        with open(path) as f:
            return f.read()
    except OSError as e:
        return f"Error reading {path}: {e}"  # returned as tool result
Defensive patterns

Strategy: try-catch

Type guard

def is_tool_exception_group(exc: BaseException) -> bool:
    return isinstance(exc, ExceptionGroup) and any(
        isinstance(e, Exception) for e in exc.exceptions
    )

Try / catch

try:
    reply = await agent.run(msg)
except ExceptionGroup as eg:
    for sub in eg.exceptions:
        logger.error("tool call failed: %r", sub)

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of agentscope-ai/agentscope@e90f1c7592 (2026-08-28). Data as JSON: /api/errors/a33cbd1eb6b61b69. Report an issue: GitHub.