microsoft/autogen · error · InvalidOperationException
Invalid streaming message type {reply.GetType().Name}
Error message
Invalid streaming message type {reply.GetType().Name} What it means
OpenAIChatRequestMessageConnector's streaming path only processes MessageEnvelope<StreamingChatCompletionsUpdate> chunks (text deltas and tool-call deltas). Any other streaming message type hits this branch; in strictMode it throws InvalidOperationException, otherwise it passes the message through untouched.
Source
Thrown at dotnet/src/AutoGen.OpenAI.V1/Middleware/OpenAIChatRequestMessageConnector.cs:80
if (update.Content.FunctionName is string functionName)
{
currentToolName = functionName;
}
else if (update.Content.ToolCallUpdate is StreamingFunctionToolCallUpdate toolCallUpdate && toolCallUpdate.Name is string toolCallName)
{
currentToolName = toolCallName;
}
var postProcessMessage = PostProcessStreamingMessage(update, currentToolName);
if (postProcessMessage != null)
{
yield return postProcessMessage;
}
}
else
{
if (this.strictMode)
{
throw new InvalidOperationException($"Invalid streaming message type {reply.GetType().Name}");
}
else
{
yield return reply;
}
}
}
}
public IMessage PostProcessMessage(IMessage message)
{
return message switch
{
IMessage<ChatResponseMessage> m => PostProcessChatResponseMessage(m.Content, m.From),
IMessage<ChatCompletions> m => PostProcessChatCompletions(m),
_ when strictMode is false => message,
_ => throw new InvalidOperationException($"Invalid return message type {message.GetType().Name}"),
};View on GitHub (pinned to 027ecf0a37)
Solutions
- Construct the connector with strictMode: false (default) so foreign streaming messages pass through
- Ensure only MessageEnvelope<StreamingChatCompletionsUpdate> items flow through the OpenAI connector's streaming path, or place custom middleware after it
- Have custom middleware wrap its output as updates or defer emission to post-processing
Example fix
// before
var connector = new OpenAIChatRequestMessageConnector(strictMode: true);
agent = agent.RegisterStreamingMiddleware(connector)
.RegisterStreamingMiddleware(myCustomYieldingMiddleware); // throws in strict mode
// after
var connector = new OpenAIChatRequestMessageConnector(strictMode: false);
agent = agent.RegisterStreamingMiddleware(connector)
.RegisterStreamingMiddleware(myCustomYieldingMiddleware); Defensive patterns
Strategy: fallback
Validate before calling
bool isUpdate = reply is MessageEnvelope<StreamingChatCompletionsUpdate>;
if (!isUpdate && connectorStrictMode) { /* route around connector */ } Type guard
static bool IsStreamingUpdate(IMessage m) =>
m is MessageEnvelope<StreamingChatCompletionsUpdate>; Try / catch
catch (InvalidOperationException ex) when (ex.Message.Contains("Invalid streaming message type"))
{
logger.LogError("Custom streaming middleware clashed with strict connector; disabling strict mode");
connector = new OpenAIChatRequestMessageConnector(strictMode: false);
} Prevention
- Use strictMode: false when stacking custom streaming middleware
- Order custom middleware after the OpenAI connector
- Emit only StreamingChatCompletionsUpdate envelopes upstream of the connector in strict mode
When it happens
Trigger: Stacking middlewares that inject custom IMessage types into the streaming pipeline ahead of this connector while it was constructed with strictMode: true, then invoking GenerateStreamingReplyAsync.
Common situations: Composing custom streaming middleware (logging, routing, caching) that yields non-update messages; mixing connectors from different provider packages on one agent with strict mode enabled.
Related errors
- Invalid streaming message type {reply.GetType().Name}
- Invalid return message type {message.GetType().Name}
- Please set OPENAI_API_KEY environment variable.
- The first message is ToolCallMessage, but the update message
- The message is not a valid message
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/58698494d206f92e.
Report an issue: GitHub.