microsoft/autogen · error · InvalidOperationException
Unsupported message type: {reply.GetType()}
Error message
Unsupported message type: {reply.GetType()} What it means
Thrown by GeminiMessageConnector's STREAMING path when strictMode is enabled and the agent's streaming reply item is not IMessage<GenerateContentResponse>. In strict mode the connector refuses to pass through foreign message types; non-strict mode simply yields them unchanged.
Source
Thrown at dotnet/src/AutoGen.Gemini/Middleware/GeminiMessageConnector.cs:69
{
// if m.Content is empty and stop reason is Stop, ignore the message
if (m.Content.Candidates.Count == 1 && m.Content.Candidates[0].Content.Parts.Count == 1 && m.Content.Candidates[0].Content.Parts[0].DataCase == Part.DataOneofCase.Text)
{
var text = m.Content.Candidates[0].Content.Parts[0].Text;
var stopReason = m.Content.Candidates[0].FinishReason;
if (string.IsNullOrEmpty(text) && stopReason == FinishReason.Stop)
{
continue;
}
}
bucket.Add(m.Content);
yield return PostProcessStreamingMessage(m.Content, agent);
}
else if (strictMode)
{
throw new InvalidOperationException($"Unsupported message type: {reply.GetType()}");
}
else
{
yield return reply;
}
// aggregate the message updates from bucket into a single message
if (bucket is { Count: > 0 })
{
var isTextMessageUpdates = bucket.All(m => m.Candidates.Count == 1 && m.Candidates[0].Content.Parts.Count == 1 && m.Candidates[0].Content.Parts[0].DataCase == Part.DataOneofCase.Text);
var isFunctionCallUpdates = bucket.Any(m => m.Candidates.Count == 1 && m.Candidates[0].Content.Parts.Count == 1 && m.Candidates[0].Content.Parts[0].DataCase == Part.DataOneofCase.FunctionCall);
if (isTextMessageUpdates)
{
var text = string.Join(string.Empty, bucket.Select(m => m.Candidates[0].Content.Parts[0].Text));
var textMessage = new TextMessage(Role.Assistant, text, agent.Name);
yield return textMessage;
}View on GitHub (pinned to 027ecf0a37)
Solutions
- Register GeminiMessageConnector directly against the GeminiChatAgent so it sees raw GenerateContentResponse streams (use the provided agent-registration helper for correct ordering)
- Run the connector in non-strict mode (default) so foreign types pass through untouched
- Remove any middleware between the Gemini agent and the connector that pre-converts messages
Example fix
// before: var agent = new GeminiChatAgent(...).RegisterStreamingMiddleware(new GeminiMessageConnector(strictMode: true)); // middleware ordering yields Core types into connector -> throw // after: var agent = new GeminiChatAgent(...).RegisterMessageConnector(); // correct order, default non-strict
Defensive patterns
Strategy: fallback
Validate before calling
null
Type guard
static bool IsGeminiStreamingReply(IMessage m) => m is IMessage<GenerateContentResponse>;
Try / catch
try { await foreach (var m in streamingGeminiAgent.GenerateStreamingReplyAsync(msgs, ct)) { } }
catch (InvalidOperationException e) when (e.Message.Contains("Unsupported message type") && strictMode)
{ /* rerun with non-strict connector: new GeminiMessageConnector() */ } Prevention
- Use the agent helper that registers the connector in the correct position
- Default to non-strict mode unless you specifically need type enforcement
When it happens
Trigger: Constructing GeminiMessageConnector(strictMode: true) and having the wrapped streaming agent yield AutoGen Core message types (TextMessageUpdate, ToolCallMessageUpdate, MessageEnvelope of other payloads) instead of Gemini GenerateContentResponse envelopes.
Common situations: Composing middleware where another middleware already converted chunks to Core types before the connector sees them, or wrapping a non-Gemini streaming agent by mistake.
Related errors
- The first message is ToolCallMessage, but the update message
- The message is not a valid message
- The recent update is not a TextMessage
- The recent update is not a ToolCallMessage
- Message type {m.GetType()} is not supported.
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/7e1f84ddd743f976.
Report an issue: GitHub.