{"record":{"id":"faae2ffa8d8bf1c0","repo":"microsoft/autogen","slug":"toolcallmessage-is-not-supported-as-user-role-in-g","errorCode":null,"errorMessage":"ToolCallMessage is not supported as user role in Gemini.","messagePattern":"ToolCallMessage is not supported as user role in Gemini\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"dotnet/src/AutoGen.Gemini/Middleware/GeminiMessageConnector.cs","lineNumber":317,"sourceCode":"\n            functionCallResultParts.Add(part);\n        }\n\n        var content = new Content\n        {\n            Parts = { functionCallResultParts },\n            Role = \"function\",\n        };\n\n        return [MessageEnvelope.Create(content, toolCallResultMessage.From)];\n    }\n\n    private IEnumerable<IMessage> ProcessToolCallMessage(ToolCallMessage toolCallMessage, IAgent agent)\n    {\n        var shouldParseAsUser = ShouldParseAsUser(toolCallMessage, agent);\n        if (strictMode && shouldParseAsUser)\n        {\n            throw new InvalidOperationException(\"ToolCallMessage is not supported as user role in Gemini.\");\n        }\n\n        var functionCallParts = new List<Part>();\n        foreach (var toolCall in toolCallMessage.ToolCalls)\n        {\n            var part = new Part\n            {\n                FunctionCall = new FunctionCall\n                {\n                    Name = toolCall.FunctionName,\n                    Args = Struct.Parser.ParseJson(toolCall.FunctionArguments),\n                }\n            };\n\n            functionCallParts.Add(part);\n        }\n        var content = new Content\n        {","sourceCodeStart":299,"sourceCodeEnd":335,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/dotnet/src/AutoGen.Gemini/Middleware/GeminiMessageConnector.cs#L299-L335","documentation":"GeminiMessageConnector.ProcessToolCallMessage throws in strict mode when a ToolCallMessage must be rendered with the Gemini 'user' role. ShouldParseAsUser decides the role; a function-call part is only valid as 'model' in the Gemini API, so a tool call attributed to someone other than the Gemini agent itself cannot be represented and strict mode rejects it.","triggerScenarios":"strictMode:true plus a ToolCallMessage whose From differs from the Gemini agent's name (e.g. a tool-call message produced by another agent in a group chat) reaching the Gemini agent.","commonSituations":"Multi-agent group chats where an assistant agent's ToolCallMessage is replayed to the Gemini agent as context; middleware forwarding tool calls between agents with strict connectors.","solutions":["Set message.From to the Gemini agent's name before sending its own ToolCallMessage history back to it.","Convert foreign ToolCallMessages into ToolCallResultMessages or a TextMessage summary before they reach a strict Gemini agent.","Disable strict mode (strictMode:false) so the connector maps it leniently.","Reorder group-chat routing so tool-call/result pairs are only sent to the agent that issued them."],"exampleFix":"// before\nvar foreign = new ToolCallMessage(calls, from: \"openai-assistant\");\nawait geminiAgent.InitiateChatAsync(null, null, foreign); // strict connector\n\n// after\nvar summary = new TextMessage(Role.User, \"openai-assistant called: \" + string.Join(\",\", calls.Select(c => c.FunctionName)), from: \"openai-assistant\");\nawait geminiAgent.SendAsync(summary);","handlingStrategy":"validation","validationCode":"if (msg is ToolCallMessage tcm && tcm.From != geminiAgent.Name)\n{\n    msg = new TextMessage(Role.User, \"tool calls: \" + string.Join(\",\", tcm.ToolCalls.Select(t => t.FunctionName)), from: tcm.From);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep tool-call/result messages local to the agent that produced them","Use strictMode only on agents with controlled inputs"],"tags":["gemini","strict-mode","tool-calls","role-mapping"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}