microsoft/autogen · error · RuntimeError

The team did not produce a final TaskResult. Check the team'

Error message

The team did not produce a final TaskResult. Check the team's run_stream method.

What it means

Raised inside ChatAgentContainer when a nested Team used as a group-chat participant finished its run_stream without ever yielding a final TaskResult event. Every compliant Team.run_stream must terminate with a TaskResult; if the inner stream ends empty (e.g., an exception was swallowed or a custom Team was implemented incorrectly), the container cannot publish a GroupChatTeamResponse and fails the outer chat.

Source

Thrown at python/packages/autogen-agentchat/src/autogen_agentchat/teams/_group_chat/_chat_agent_container.py:103

    @event
    async def handle_request(self, message: GroupChatRequestPublish, ctx: MessageContext) -> None:
        """Handle a content request event by passing the messages in the buffer
        to the delegate agent and publish the response."""
        if isinstance(self._agent, Team):
            try:
                stream = self._agent.run_stream(
                    task=self._message_buffer,
                    cancellation_token=ctx.cancellation_token,
                    output_task_messages=False,
                )
                result: TaskResult | None = None
                async for team_event in stream:
                    if isinstance(team_event, TaskResult):
                        result = team_event
                    else:
                        await self._log_message(team_event)
                if result is None:
                    raise RuntimeError(
                        "The team did not produce a final TaskResult. Check the team's run_stream method."
                    )
                self._message_buffer.clear()
                # Publish the team response to the group chat.
                await self.publish_message(
                    GroupChatTeamResponse(result=result, name=self._agent.name),
                    topic_id=DefaultTopicId(type=self._parent_topic_type),
                    cancellation_token=ctx.cancellation_token,
                )
            except Exception as e:
                # Publish the error to the group chat.
                error_message = SerializableException.from_exception(e)
                await self.publish_message(
                    GroupChatError(error=error_message),
                    topic_id=DefaultTopicId(type=self._parent_topic_type),
                    cancellation_token=ctx.cancellation_token,
                )
                # Raise the error to the runtime.

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Ensure your custom Team.run_stream always yields a TaskResult as its final event on every code path (including early exits).
  2. If cancellation can interrupt the inner run, catch and still emit TaskResult with the messages collected so far.
  3. Prefer composing built-in teams (RoundRobin, Selector, GraphFlow) as the nested participant instead of implementing run_stream manually.

Example fix

// before
class MyTeam(Team):
    async def run_stream(self, task, cancellation_token):
        for msg in self._produce(task):
            yield msg
        # returns without TaskResult -> error

// after
class MyTeam(Team):
    async def run_stream(self, task, cancellation_token):
        messages = []
        for msg in self._produce(task):
            messages.append(msg)
            yield msg
        yield TaskResult(messages=messages, stop_reason="done")
Defensive patterns

Strategy: validation

Validate before calling

async def run_stream_yields_result(team: Team, task) -> bool:
    found = False
    async for ev in team.run_stream(task):
        if isinstance(ev, TaskResult):
            found = True
    return found
# unit-test this for every custom Team before nesting it in a group chat

Try / catch

try:
    async for ev in outer_team.run_stream(task):
        ...
except RuntimeError as e:
    if "did not produce a final TaskResult" in str(e):
        # inspect the inner Team.run_stream implementation; add a final TaskResult yield
        ...

Prevention

When it happens

Trigger: Wrapping a custom Team subclass (implementing run_stream yourself) that returns without yielding TaskResult; an inner team whose stream is cut off by cancellation or by an exception raised before the final event; incompatible/older Team implementations after a version upgrade.

Common situations: Using a hand-rolled Team as a participant in SelectorGroupChat/Swarm/GraphFlow; upgrading autogen-agentchat where the Team streaming contract changed; inner team cancelled mid-run and the cancellation path skips the final event.

Related errors


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/4705d77128e828a2. Report an issue: GitHub.