microsoft/semantic-kernel · error · NotSupportedException

Unsupported role {message.Role.Label}. Only system, user, de

Error message

Unsupported role {message.Role.Label}. Only system, user, developer or assistant roles are allowed.

What it means

ChatContentMessageExtensions.ToResponseItem converts a ChatMessageContent into an OpenAI Responses-API ResponseItem. It only recognizes the SYSTEM, USER, DEVELOPER, and ASSISTANT role labels; any other role throws NotSupportedException.

Source

Thrown at dotnet/src/Agents/OpenAI/Extensions/ChatContentMessageExtensions.cs:54

        return messages.Select(message => message.ToThreadInitializationMessage());
    }

    /// <summary>
    /// Converts a <see cref="ChatMessageContent"/> instance to a <see cref="ResponseItem"/>.
    /// </summary>
    /// <param name="message">The chat message content to convert.</param>
    /// <returns>A <see cref="ResponseItem"/> instance.</returns>
    public static ResponseItem ToResponseItem(this ChatMessageContent message)
    {
        var items = message.Items;
        IEnumerable<ResponseContentPart> contentParts = items.Select(item => item.ToResponseContentPart());
        return message.Role.Label.ToUpperInvariant() switch
        {
            "SYSTEM" => ResponseItem.CreateSystemMessageItem(contentParts),
            "USER" => ResponseItem.CreateUserMessageItem(contentParts),
            "DEVELOPER" => ResponseItem.CreateDeveloperMessageItem(contentParts),
            "ASSISTANT" => ResponseItem.CreateAssistantMessageItem(contentParts),
            _ => throw new NotSupportedException($"Unsupported role {message.Role.Label}. Only system, user, developer or assistant roles are allowed."),
        };
    }
}

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Filter the chat history to only system/user/developer/assistant messages before sending to a Responses-API agent.
  2. Convert tool-result messages into a user-role message (text) when the Responses API requires it.
  3. Use the correct agent type (OpenAIAssistantAgent vs OpenAIResponseAgent) for your message stream.
  4. Log message.Role.Label before conversion to detect unsupported roles.

Example fix

// before
var items = history.Select(m => m.ToResponseItem());
// after
var allowed = new[] { "SYSTEM", "USER", "DEVELOPER", "ASSISTANT" };
var items = history
    .Where(m => allowed.Contains(m.Role.Label.ToUpperInvariant()))
    .Select(m => m.ToResponseItem());
Defensive patterns

Strategy: type-guard

Validate before calling

var allowed = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "system", "user", "developer", "assistant" };
if (!allowed.Contains(message.Role.Label))
    throw new ArgumentException($"Role '{message.Role.Label}' cannot be converted to a ResponseItem.");

Type guard

static bool IsSupportedResponseRole(ChatMessageContent m) =>
    m.Role.Label.ToUpperInvariant() is "SYSTEM" or "USER" or "DEVELOPER" or "ASSISTANT";

Try / catch

try { var item = message.ToResponseItem(); }
catch (NotSupportedException ex) when (ex.Message.Contains("Unsupported role")) {
    // map tool/other messages to a user message, or drop them
}

Prevention

When it happens

Trigger: Passing a ChatMessageContent whose Role is Tool (or a custom AuthorRole) into the Responses-API conversion path used by OpenAIResponseAgent.

Common situations: Feeding a tool-result message or function-call content into a Responses-API agent that only accepts the four conversational roles; mixing Assistant-API message shapes with the Responses converter.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/0b7b6af7e9c28e9f. Report an issue: GitHub.