{"record":{"id":"e37eaeaa82a21432","repo":"microsoft/autogen","slug":"message-type-m-gettype-is-not-supported","errorCode":null,"errorMessage":"Message type {m.GetType()} is not supported.","messagePattern":"Message type (.+?) is not supported\\.","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"dotnet/src/AutoGen.Gemini/GeminiChatAgent.cs","lineNumber":162,"sourceCode":"    }\n\n    public async IAsyncEnumerable<IMessage> GenerateStreamingReplyAsync(IEnumerable<IMessage> messages, GenerateReplyOptions? options = null, [EnumeratorCancellation] CancellationToken cancellationToken = default)\n    {\n        var request = BuildChatRequest(messages, options);\n        var response = this.client.GenerateContentStreamAsync(request);\n\n        await foreach (var item in response.WithCancellation(cancellationToken).ConfigureAwait(false))\n        {\n            yield return MessageEnvelope.Create(item, this.Name);\n        }\n    }\n\n    private GenerateContentRequest BuildChatRequest(IEnumerable<IMessage> messages, GenerateReplyOptions? options)\n    {\n        var geminiMessages = messages.Select(m => m switch\n        {\n            IMessage<Content> contentMessage => contentMessage.Content,\n            _ => throw new NotSupportedException($\"Message type {m.GetType()} is not supported.\")\n        });\n\n        // there are several rules applies to the messages that can be sent to Gemini in a multi-turn chat\n        // - The first message must be from the user or function\n        // - The (user|model) roles must alternate e.g. (user, model, user, model, ...)\n        // - The last message must be from the user or function\n\n        // check if the first message is from the user\n        if (geminiMessages.FirstOrDefault()?.Role != \"user\" && geminiMessages.FirstOrDefault()?.Role != \"function\")\n        {\n            throw new ArgumentException(\"The first message must be from the user or function\", nameof(messages));\n        }\n\n        // check if the last message is from the user\n        if (geminiMessages.LastOrDefault()?.Role != \"user\" && geminiMessages.LastOrDefault()?.Role != \"function\")\n        {\n            throw new ArgumentException(\"The last message must be from the user or function\", nameof(messages));\n        }","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/dotnet/src/AutoGen.Gemini/GeminiChatAgent.cs#L144-L180","documentation":"Thrown by GeminiChatAgent.BuildChatRequest when a message in the conversation is not an IMessage<Content> (the Gemini-native content envelope). AutoGen's Gemini agent does not convert arbitrary message types, so any TextMessage/ToolCallMessage sent raw into GeminiChatAgent triggers NotSupportedException with the offending CLR type name.","triggerScenarios":"Sending messages (TextMessage, ToolCallMessage, ImageMessage, or custom IMessage) directly to GeminiChatAgent.GenerateReplyAsync without the GeminiMessageConnector middleware in the pipeline.","commonSituations":"Using the low-level GeminiChatAgent instead of the factory helper that registers GeminiMessageConnector; mixing agents from different providers in one chat and forwarding their replies verbatim to Gemini; upgrades where connector registration moved from implicit to explicit.","solutions":["Register GeminiMessageConnector middleware on the Gemini agent so messages are converted to IMessage<Content> before the request is built (use the Gemini agent creation helper which does this for you)","If you build GeminiChatAgent manually, wrap payloads yourself in MessageEnvelope.Create(Content, from)","In multi-provider chats, insert the appropriate provider connector middleware on each agent"],"exampleFix":"// before:\nvar agent = new GeminiChatAgent(...);\nawait agent.GenerateReplyAsync(new[] { new TextMessage(Role.User, \"hi\") }); // throws\n// after:\nvar agent = new GeminiChatAgent(...)\n    .RegisterMessageConnector(); // GeminiMessageConnector converts TextMessage -> Content","handlingStrategy":"type-guard","validationCode":"// Verify every outgoing message is Gemini-native before calling the raw agent\nif (messages.Any(m => m is not IMessage<Content>))\n    messages = ConvertViaConnector(messages); // or ensure connector middleware is registered","typeGuard":"static bool AllGeminiNative(IEnumerable<IMessage> msgs) =>\n    msgs.All(m => m is IMessage<Content>);","tryCatchPattern":"try { return await geminiAgent.GenerateReplyAsync(messages, options, ct); }\ncatch (NotSupportedException e) when (e.Message.Contains(\"not supported\"))\n{ /* register GeminiMessageConnector on the agent and retry */ }","preventionTips":["Always create Gemini agents via the library helper that registers the message connector","Never forward other providers' messages verbatim to GeminiChatAgent"],"tags":["autogen","gemini","message-conversion","middleware"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}