{"record":{"id":"945dd24ef952b7e2","repo":"microsoft/semantic-kernel","slug":"invalid-role-role-945dd2","errorCode":null,"errorMessage":"Invalid role: {role}","messagePattern":"Invalid role: (.+?)","errorType":"exception","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Connectors/Connectors.Amazon/Bedrock/Core/BedrockModelUtilities.cs","lineNumber":35,"sourceCode":"    /// <summary>\n    /// Maps the AuthorRole to the corresponding ConversationRole because AuthorRole is static and { readonly get; }. Only called if AuthorRole is User or Assistant (System set outside/beforehand).\n    /// </summary>\n    /// <param name=\"role\">The AuthorRole to be converted to ConversationRole</param>\n    /// <returns>The corresponding ConversationRole</returns>\n    /// <exception cref=\"ArgumentOutOfRangeException\">Thrown if invalid role.</exception>\n    internal static ConversationRole MapAuthorRoleToConversationRole(AuthorRole role)\n    {\n        if (role == AuthorRole.User)\n        {\n            return ConversationRole.User;\n        }\n\n        if (role == AuthorRole.Assistant)\n        {\n            return ConversationRole.Assistant;\n        }\n\n        throw new ArgumentOutOfRangeException($\"Invalid role: {role}\");\n    }\n\n    /// <summary>\n    /// Gets the system messages from the ChatHistory and adds them to the ConverseRequest System parameter.\n    /// </summary>\n    /// <param name=\"chatHistory\">The ChatHistory object to be parsed.</param>\n    /// <returns>The list of SystemContentBlock for the converse request.</returns>\n    internal static List<SystemContentBlock> GetSystemMessages(ChatHistory chatHistory)\n    {\n        return chatHistory\n            .Where(m => m.Role == AuthorRole.System)\n            .Select(m => new SystemContentBlock { Text = m.Content })\n            .ToList();\n    }\n\n    /// <summary>\n    /// Creates the list of user and assistant messages for the Converse Request from the Chat History.\n    /// </summary>","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/dotnet/src/Connectors/Connectors.Amazon/Bedrock/Core/BedrockModelUtilities.cs#L17-L53","documentation":"BedrockModelUtilities.MapAuthorRoleToConversationRole converts an SK AuthorRole to a Bedrock ConversationRole, but only handles User and Assistant. System is intentionally excluded (it is extracted separately by GetSystemMessages), and any other role falls through to ArgumentOutOfRangeException. This is reached when building the Bedrock message list from ChatHistory.","triggerScenarios":"A ChatHistory contains a message whose Role is neither User, Assistant, nor System (for example a custom AuthorRole like \"tool\", \"function\", or any non-standard string) and that message is not filtered out before BuildMessageList calls MapAuthorRoleToConversationRole. Note BuildMessageList only filters m.Role != AuthorRole.System, so custom roles survive into the mapping.","commonSituations":"Adding tool/function-call messages or custom roles to ChatHistory used with the Bedrock chat completion connector. Mixing ChatHistory built for function-calling (which may set non-standard roles) into a Bedrock request. Library version that does not support tool roles yet.","solutions":["Ensure every ChatHistory message passed to the Bedrock connector uses AuthorRole.User, AuthorRole.Assistant, or AuthorRole.System only.","Filter or remap custom roles (tool/function) to Assistant before invoking the Bedrock chat completion service.","Upgrade Connectors.Amazon if a newer version natively supports the role you need."],"exampleFix":"// before - custom role reaches the Bedrock builder\nchatHistory.AddMessage(new AuthorRole(\"tool\"), \"{\\\"result\\\": 42}\");\nvar result = await chatCompletion.GetChatMessageContentAsync(chatHistory);\n// -> ArgumentOutOfRangeException: Invalid role: tool\n\n// after - remap tool results to Assistant before the Bedrock call\nfor (int i = 0; i < chatHistory.Count; i++)\n{\n    if (chatHistory[i].Role != AuthorRole.User\n        && chatHistory[i].Role != AuthorRole.Assistant\n        && chatHistory[i].Role != AuthorRole.System)\n    {\n        chatHistory[i] = new ChatMessageContent(AuthorRole.Assistant, chatHistory[i].Content);\n    }\n}","handlingStrategy":"validation","validationCode":"// Before invoking the Bedrock chat completion service, ensure every ChatHistory\n// message uses one of the supported AuthorRoles.\nstatic bool IsBedrockSupportedRole(AuthorRole? role)\n    => role == AuthorRole.User || role == AuthorRole.Assistant || role == AuthorRole.System;\n\nforeach (var m in chatHistory)\n{\n    if (!IsBedrockSupportedRole(m.Role))\n        throw new InvalidOperationException($\"ChatHistory contains unsupported role '{m.Role}' for Bedrock.\");\n}","typeGuard":"static bool IsBedrockSupportedRole(AuthorRole? role)\n    => role == AuthorRole.User || role == AuthorRole.Assistant || role == AuthorRole.System;","tryCatchPattern":"try\n{\n    var result = await bedrockChatCompletion.GetChatMessageContentAsync(chatHistory, settings, ct);\n}\ncatch (ArgumentOutOfRangeException ex) when (ex.Message.Contains(\"Invalid role\"))\n{\n    // A non User/Assistant/System role reached the builder. Sanitize ChatHistory and retry.\n    logger.LogWarning(ex, \"ChatHistory contained an unsupported role for Bedrock.\");\n}","preventionTips":["Only add User, Assistant, and System messages to ChatHistory used with Bedrock.","Remap tool/function result messages to Assistant before sending to Bedrock.","Validate ChatHistory roles in a helper before every Bedrock call."],"tags":["csharp","dotnet","semantic-kernel","bedrock","aws","role-mapping","chathistory"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}