microsoft/autogen · error · ValueError

No stop reason found

Error message

No stop reason found

What it means

Raised at the end of AzureAIChatCompletionClient.create_stream() when the entire streamed response finished without any chunk carrying a finish_reason (the local finish_reason variable stayed None). CreateResult requires a FinishReasons value, so the client fails instead of fabricating one. Typical causes are transport truncation (network drop, timeout, content filter aborting mid-stream) or a service bug where the terminal chunk is never delivered.

Source

Thrown at python/packages/autogen-ext/src/autogen_ext/models/azure/_azure_ai_client.py:558

            if choice and choice.delta.tool_calls is not None:
                for tool_call_chunk in choice.delta.tool_calls:
                    # print(tool_call_chunk)
                    if "index" in tool_call_chunk:
                        idx = tool_call_chunk["index"]
                    else:
                        idx = tool_call_chunk.id
                    if idx not in full_tool_calls:
                        full_tool_calls[idx] = FunctionCall(id="", arguments="", name="")

                    full_tool_calls[idx].id += tool_call_chunk.id
                    full_tool_calls[idx].name += tool_call_chunk.function.name
                    full_tool_calls[idx].arguments += tool_call_chunk.function.arguments

        if chunk and chunk.usage:
            prompt_tokens = chunk.usage.prompt_tokens

        if finish_reason is None:
            raise ValueError("No stop reason found")

        content: Union[str, List[FunctionCall]]

        if len(content_deltas) > 1:
            content = "".join(content_deltas)
            if chunk and chunk.usage:
                completion_tokens = chunk.usage.completion_tokens
            else:
                completion_tokens = 0
        else:
            content = list(full_tool_calls.values())

            if len(content_deltas) > 0:
                thought = "".join(content_deltas)

        usage = RequestUsage(
            completion_tokens=completion_tokens,
            prompt_tokens=prompt_tokens,

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Wrap stream consumption in try/except ValueError('No stop reason found') and retry the request (optionally with smaller max_tokens to shorten the stream)
  2. Increase/disable idle timeouts on proxies or HTTP client (e.g. httpx timeout config)
  3. If reproducible with short prompts, capture the raw stream (autogen logging TRACE) and report — the service is closing without a terminal chunk

Example fix

# before
async for chunk in client.create_stream(msgs):
    print(chunk)

# after
for attempt in range(3):
    try:
        async for chunk in client.create_stream(msgs):
            print(chunk)
        break
    except ValueError as e:
        if "No stop reason" not in str(e) or attempt == 2:
            raise
Defensive patterns

Strategy: retry

Try / catch

for attempt in range(MAX_RETRIES):
    try:
        async for chunk in client.create_stream(msgs):
            process(chunk)
        break
    except ValueError as e:
        if "No stop reason found" not in str(e) or attempt == MAX_RETRIES - 1:
            raise
        await backoff(attempt)

Prevention

When it happens

Trigger: Streaming a long generation that gets cut off (connection reset, gateway timeout at 60s/120s, proxy buffering limits); content_filter events that close the stream without a finish_reason; empty streams from misrouted deployments.

Common situations: Long completions behind corporate proxies or Azure Gateway with aggressive idle timeouts; intermittent networking during containerized runs; GitHub Models rate-limiting that terminates the SSE stream early.

Related errors


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