{"record":{"id":"b2d1111649d7028e","repo":"microsoft/semantic-kernel","slug":"role-message-role-is-not-supported","errorCode":null,"errorMessage":"Role {message.Role} is not supported.","messagePattern":"Role (.+?) is not supported\\.","errorType":"validation","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Connectors/Connectors.OpenAI/Core/ClientCore.ChatCompletion.cs","lineNumber":885,"sourceCode":"            }\n\n            // This check is necessary to prevent an exception that will be thrown if the toolCalls collection is empty.\n            // HTTP 400 (invalid_request_error:) [] should be non-empty - 'messages.3.tool_calls'\n            if (toolCalls.Count == 0)\n            {\n                return [new AssistantChatMessage(message.Content ?? string.Empty) { ParticipantName = message.AuthorName }];\n            }\n\n            var assistantMessage = new AssistantChatMessage(SanitizeFunctionNames(toolCalls)) { ParticipantName = message.AuthorName };\n\n            // If message content is null, adding it as empty string,\n            // because chat message content must be string.\n            assistantMessage.Content.Add(message.Content ?? string.Empty);\n\n            return [assistantMessage];\n        }\n\n        throw new NotSupportedException($\"Role {message.Role} is not supported.\");\n    }\n\n    private static ChatMessageContentPart GetImageContentItem(ImageContent imageContent)\n    {\n        ChatImageDetailLevel? detailLevel = GetChatImageDetailLevel(imageContent);\n\n        if (imageContent.Data is { IsEmpty: false } data)\n        {\n            return ChatMessageContentPart.CreateImagePart(BinaryData.FromBytes(data), imageContent.MimeType, detailLevel);\n        }\n\n        if (imageContent.Uri is not null)\n        {\n            return ChatMessageContentPart.CreateImagePart(imageContent.Uri, detailLevel);\n        }\n\n        throw new ArgumentException($\"{nameof(ImageContent)} must have either Data or a Uri.\");\n    }","sourceCodeStart":867,"sourceCodeEnd":903,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/dotnet/src/Connectors/Connectors.OpenAI/Core/ClientCore.ChatCompletion.cs#L867-L903","documentation":"Terminal throw at the end of the per-role message builder. The method handles System, User, Assistant, and Tool roles explicitly; reaching this line means message.Role is none of those (e.g. an unknown/custom AuthorRole label). OpenAI's chat protocol has no slot for such a role, so the request cannot be serialized.","triggerScenarios":"Passing a ChatMessageContent whose AuthorRole is a custom label or a role outside System/User/Assistant/Tool (e.g. AuthorRole.System analog misspelled, or a generic 'developer' role not yet handled by this version).","commonSituations":"Using newer role vocabulary (developer) on an older connector build; constructing messages with string-based custom roles; deserializing history that used an experimental role.","solutions":["Remap the message to one of System, User, Assistant, or Tool before sending.","If you need a 'developer' role, upgrade the connector to a version that maps it.","Avoid creating AuthorRole instances from arbitrary strings."],"exampleFix":"// before\nhistory.Add(new ChatMessageContent(new AuthorRole(\"developer\"), \"act as X\"));\n// after\nhistory.Add(new ChatMessageContent(AuthorRole.System, \"act as X\"));","handlingStrategy":"validation","validationCode":"static readonly HashSet<AuthorRole> SupportedRoles = new() { AuthorRole.System, AuthorRole.User, AuthorRole.Assistant, AuthorRole.Tool };\nstatic void EnsureSupportedRole(ChatMessageContent m) { if (!SupportedRoles.Contains(m.Role)) throw new ArgumentException($\"Remap role {m.Role} to System/User/Assistant/Tool\"); }","typeGuard":"static bool IsSupportedRole(AuthorRole? r) => r is not null && SupportedRoles.Contains(r);","tryCatchPattern":"try { await client.GetChatCompletionAsync(history); }\ncatch (NotSupportedException ex) when (ex.Message.Contains(\"is not supported\")) { /* remap role and retry */ }","preventionTips":["Do not construct AuthorRole from arbitrary strings.","Map experimental roles (developer) to System on older builds."],"tags":["openai","chat-completion","chat-role","message-mapping"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}