microsoft/autogen · error · InvalidOperationException

Only one choice is supported in streaming response

Error message

Only one choice is supported in streaming response

What it means

InvalidOperationException thrown in OpenAIChatAgent.GenerateStreamingReplyAsync when a StreamingChatCompletionUpdate contains more than one content part (update.ContentUpdate.Count > 1). The agent yields updates as simple envelopes and downstream middleware assumes a single content part per chunk, so multi-part streaming updates (e.g. interleaved text and image parts) are rejected.

Source

Thrown at dotnet/src/AutoGen.OpenAI/Agent/OpenAIChatAgent.cs:111

        var chatHistory = this.CreateChatMessages(messages);
        var settings = this.CreateChatCompletionsOptions(options);
        var reply = await this.chatClient.CompleteChatAsync(chatHistory, settings, cancellationToken);
        return new MessageEnvelope<ChatCompletion>(reply.Value, from: this.Name);
    }

    public async IAsyncEnumerable<IMessage> GenerateStreamingReplyAsync(
        IEnumerable<IMessage> messages,
        GenerateReplyOptions? options = null,
        [EnumeratorCancellation] CancellationToken cancellationToken = default)
    {
        var chatHistory = this.CreateChatMessages(messages);
        var settings = this.CreateChatCompletionsOptions(options);
        var response = this.chatClient.CompleteChatStreamingAsync(chatHistory, settings, cancellationToken);
        await foreach (var update in response.WithCancellation(cancellationToken))
        {
            if (update.ContentUpdate.Count > 1)
            {
                throw new InvalidOperationException("Only one choice is supported in streaming response");
            }

            yield return new MessageEnvelope<StreamingChatCompletionUpdate>(update, from: this.Name);
        }
    }

    private IEnumerable<ChatMessage> CreateChatMessages(IEnumerable<IMessage> messages)
    {
        var oaiMessages = messages.Select(m => m switch
        {
            IMessage<ChatMessage> chatMessage => chatMessage.Content,
            _ => throw new ArgumentException("Invalid message type")
        });

        // add system message if there's no system message in messages
        if (!oaiMessages.Any(m => m is SystemChatMessage) && systemMessage is not null)
        {
            oaiMessages = new[] { new SystemChatMessage(systemMessage) }.Concat(oaiMessages);

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Restrict the request to text-only output (remove audio/image options from ChatCompletionOptions)
  2. Use non-streaming GenerateReplyAsync if the model legitimately produces multi-part content
  3. Bypass OpenAIChatAgent and consume ChatClient.CompleteChatStreamingAsync directly to handle multi-part updates yourself

Example fix

// before
await foreach (var msg in agent.GenerateStreamingReplyAsync(messages)) { } // multi-part chunk throws

// after
var reply = await agent.GenerateReplyAsync(messages); // non-streaming path
Defensive patterns

Strategy: fallback

Try / catch

catch (InvalidOperationException ex) when (ex.Message == "Only one choice is supported in streaming response") { /* fall back to non-streaming GenerateReplyAsync */ }

Prevention

When it happens

Trigger: Streaming from a model whose chunks carry multiple ChatMessageContentPart items in one update — typically multimodal/image-output models or audio+text streams — via OpenAIChatAgent in AutoGen.OpenAI.

Common situations: Using gpt-4o-audio-preview or image-generation-capable models through this agent; enabling multiple modalities in ChatCompletionOptions while streaming; API/SDK changes that split content into multiple parts per chunk.

Related errors


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