microsoft/autogen · error · InvalidOperationException

Unsupported message type: {message.GetType()}

Error message

Unsupported message type: {message.GetType()}

What it means

GeminiMessageConnector.ProcessMultiModalMessage only knows how to map two content types inside a MultiModalMessage: TextMessage -> Part.Text and ImageMessage -> inline image part. Any other IMessage inside multiModalMessage.Content throws this InvalidOperationException naming the offending type.

Source

Thrown at dotnet/src/AutoGen.Gemini/Middleware/GeminiMessageConnector.cs:358

        return [MessageEnvelope.Create(content, toolCallMessage.From)];
    }

    private IEnumerable<IMessage> ProcessMultiModalMessage(MultiModalMessage multiModalMessage, IAgent agent)
    {
        var parts = new List<Part>();
        foreach (var message in multiModalMessage.Content)
        {
            if (message is TextMessage textMessage)
            {
                parts.Add(new Part { Text = textMessage.Content });
            }
            else if (message is ImageMessage imageMessage)
            {
                parts.Add(CreateImagePart(imageMessage));
            }
            else
            {
                throw new InvalidOperationException($"Unsupported message type: {message.GetType()}");
            }
        }

        var shouldParseAsUser = ShouldParseAsUser(multiModalMessage, agent);

        if (strictMode && !shouldParseAsUser)
        {
            // image message is not supported as model role in Gemini
            throw new InvalidOperationException("Image message is not supported as model role in Gemini.");
        }

        var content = new Content
        {
            Parts = { parts },
            Role = shouldParseAsUser ? "user" : "model",
        };

        return [MessageEnvelope.Create(content, multiModalMessage.From)];

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Reduce MultiModalMessage content to TextMessage + ImageMessage only before sending to a Gemini agent.
  2. Serialize non-supported modalities to text descriptions, or extend the connector with your own middleware that maps the extra type to a Gemini Part.
  3. Check the exception's type name to find which content item leaked in.

Example fix

// before
var mm = new MultiModalMessage(Role.User, [text, image, new AudioMessage(...)], from: "user");

// after
var mm = new MultiModalMessage(Role.User, [text, image], from: "user");
Defensive patterns

Strategy: type-guard

Validate before calling

var unsupported = multiModalMessage.Content.Where(c => c is not TextMessage and not ImageMessage).ToList();
if (unsupported.Count > 0) { /* remove or convert items before sending */ }

Type guard

static bool IsGeminiMultimodalContent(IEnumerable<IMessage> content) => content.All(m => m is TextMessage or ImageMessage);

Prevention

When it happens

Trigger: Building a MultiModalMessage whose Content collection includes something other than TextMessage/ImageMessage — e.g. an AudioMessage, another MultiModalMessage, or a custom message class.

Common situations: Migrating multimodal pipelines that previously targeted OpenAI/GPT-4V connectors with richer content types; adding new modalities (audio, video) without a corresponding connector mapping.

Related errors


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