microsoft/autogen · error · AssertionError

The stream should have returned the final result.

Error message

The stream should have returned the final result.

What it means

on_messages iterates on_messages_stream and asserts a final Response event arrives. If the stream finishes without ever yielding a Response (e.g. it was cancelled, an exception path ended the generator, or a bug/edge case dropped the terminal event), the AssertionError fires — an invariant violation, not an expected user error.

Source

Thrown at python/packages/autogen-ext/src/autogen_ext/agents/azure/_azure_ai_agent.py:649

        It delegates to on_messages_stream and returns the final response.

        Args:
            messages (Sequence[BaseChatMessage]): The messages to process
            cancellation_token (CancellationToken): Token for cancellation handling
            message_limit (int, optional): Maximum number of messages to retrieve from the thread

        Returns:
            Response: The agent's response, including the chat message and any inner events

        Raises:
            AssertionError: If the stream doesn't return a final result
        """
        async for message in self.on_messages_stream(
            messages=messages, cancellation_token=cancellation_token, message_limit=message_limit
        ):
            if isinstance(message, Response):
                return message
        raise AssertionError("The stream should have returned the final result.")

    async def on_messages_stream(
        self,
        messages: Sequence[BaseChatMessage],
        cancellation_token: Optional[CancellationToken] = None,
        message_limit: int = 1,
        polling_interval: float = 0.5,
    ) -> AsyncGenerator[AgentEvent | ChatMessage | Response, None]:
        """
        Process incoming messages and yield streaming responses from the Azure AI agent.

        This method handles the complete interaction flow with the Azure AI agent:
        1. Processing input messages
        2. Creating and monitoring a run
        3. Handling tool calls and their results
        4. Retrieving and returning the agent's final response

        The method yields events during processing (like tool calls) and finally yields

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. If cancelling is intended, don't await on_messages afterwards — treat CancelledError as the outcome rather than letting the loop fall through.
  2. Upgrade autogen-ext — stream/Response invariants have had fixes across releases.
  3. Don't wrap on_messages_stream in a generator that filters events unless you forward Response objects.
  4. If reproducible without cancellation, capture the full event sequence and file an issue; it indicates a bug.

Example fix

# before
resp = await agent.on_messages(msgs, ct)  # ct already cancelled
# after
if ct.is_cancelled():
    return
resp = await agent.on_messages(msgs, ct)
Defensive patterns

Strategy: try-catch

Validate before calling

if cancellation_token and cancellation_token.is_cancelled():
    return  # don't start/await on_messages

Try / catch

try:
    resp = await agent.on_messages(msgs, ct)
except AssertionError:
    if ct.is_cancelled():
        handle_cancelled()
    else:
        raise  # genuine bug — capture the event stream and report

Prevention

When it happens

Trigger: The CancellationToken cancels mid-stream so the generator exits without a final Response; an upstream exception inside on_messages_stream is swallowed by an inner handler; edge cases (message_limit reached before any response event) in specific versions.

Common situations: Cancelling a run via CancellationToken and still awaiting on_messages; wrapping the stream in custom generators that drop the final event; version-specific bugs after upgrading autogen-ext.

Related errors


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