huggingface/smolagents · error · ValueError

Incorrect role {role}, only {MessageRole.roles()} are suppor

Error message

Incorrect role {role}, only {MessageRole.roles()} are supported for now.

What it means

get_clean_message_list normalizes a chat history into provider-ready messages; every message's role must be one of MessageRole.roles() (system/user/assistant/tool). Dict messages are converted via ChatMessage.from_dict, and then the role is checked before role conversion and image encoding. Any other role string (including None, empty string, or 'function') raises ValueError listing the valid roles.

Source

Thrown at src/smolagents/models.py:355

) -> list[dict[str, Any]]:
    """
    Creates a list of messages to give as input to the LLM. These messages are dictionaries and chat template compatible with transformers LLM chat template.
    Subsequent messages with the same role will be concatenated to a single message.

    Args:
        message_list (`list[ChatMessage | dict]`): List of chat messages. Mixed types are allowed.
        role_conversions (`dict[MessageRole, MessageRole]`, *optional* ): Mapping to convert roles.
        convert_images_to_image_urls (`bool`, default `False`): Whether to convert images to image URLs.
        flatten_messages_as_text (`bool`, default `False`): Whether to flatten messages as text.
    """
    output_message_list: list[dict[str, Any]] = []
    message_list = deepcopy(message_list)  # Avoid modifying the original list
    for message in message_list:
        if isinstance(message, dict):
            message = ChatMessage.from_dict(message)
        role = message.role
        if role not in MessageRole.roles():
            raise ValueError(f"Incorrect role {role}, only {MessageRole.roles()} are supported for now.")

        if role in role_conversions:
            message.role = role_conversions[role]  # type: ignore
        # encode images if needed
        if isinstance(message.content, list):
            for element in message.content:
                assert isinstance(element, dict), "Error: this element should be a dict:" + str(element)
                if element["type"] == "image":
                    assert not flatten_messages_as_text, f"Cannot use images with {flatten_messages_as_text=}"
                    if convert_images_to_image_urls:
                        element.update(
                            {
                                "type": "image_url",
                                "image_url": {"url": make_image_url(encode_image_base64(element.pop("image")))},
                            }
                        )
                    else:
                        element["image"] = encode_image_base64(element["image"])

View on GitHub (pinned to 30bb116109)

Solutions

  1. Map your history's roles to MessageRole members (system/user/assistant/tool) before passing it in
  2. Use ChatMessage.from_dict on well-formed dicts and validate early
  3. Inspect the failing message (role printed in the error) and fix or drop it

Example fix

# before
messages = [{"role": "function", "content": "42"}]
model.get_clean_message_list(messages)

# after
messages = [{"role": "tool", "content": "42"}]
model.get_clean_message_list(messages)
Defensive patterns

Strategy: type-guard

Validate before calling

from smolagents.messages import MessageRole
VALID = set(MessageRole.roles())
history = [m if m.get('role') in VALID else {**m, 'role': 'user'} for m in history]

Type guard

from smolagents.messages import MessageRole

def has_valid_roles(messages) -> bool:
    roles = set(MessageRole.roles())
    return all((m['role'] if isinstance(m, dict) else m.role) in roles for m in messages)

Try / catch

try:
    clean = model.get_clean_message_list(messages)
except ValueError as e:
    if 'Incorrect role' in str(e):
        messages = sanitize_roles(messages)  # map unknown roles to 'user'

Prevention

When it happens

Trigger: Passing a message list containing a dict or ChatMessage with an invalid role, e.g. {'role': 'tool_call', ...}, {'role': None}, or history built from another library's role names, to model methods or _prepare_completion_kwargs via agent.run([...]).

Common situations: Building message history manually or porting it from OpenAI/LangChain formats where roles differ; deserializing stored history with missing/corrupted role fields; typos like 'assitant'.

Related errors


AI-assisted analysis of huggingface/smolagents@30bb116109 (2026-08-28). Data as JSON: /api/errors/0022c11937249ba5. Report an issue: GitHub.