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
- Map your history's roles to MessageRole members (system/user/assistant/tool) before passing it in
- Use ChatMessage.from_dict on well-formed dicts and validate early
- 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
- Build history with ChatMessage and MessageRole enums instead of raw dicts
- Map roles from other frameworks (function->tool) when importing history
- Validate roles before agent.run/model calls
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
- Error during jinja template rendering: {type(e).__name__}: {
- Cannot specify both 'messages' and 'steps' parameters. Use '
- The 'system_prompt' property is read-only. Use 'self.prompt_
- Agent name '{name}' must be a valid Python identifier and no
- Each tool or managed_agent should have a unique name! You pa
AI-assisted analysis of huggingface/smolagents@30bb116109 (2026-08-28).
Data as JSON: /api/errors/0022c11937249ba5.
Report an issue: GitHub.