microsoft/autogen · error · ValueError
Task must be a string, a BaseChatMessage, or a list of BaseC
Error message
Task must be a string, a BaseChatMessage, or a list of BaseChatMessage.
What it means
The task parameter of run()/run_stream() accepts exactly three shapes: a str, a single BaseChatMessage, or a list of BaseChatMessage. Any other type (int, dict, tuple, an agent event, None-like sentinels) hits the final else branch.
Source
Thrown at python/packages/autogen-agentchat/src/autogen_agentchat/teams/_group_chat/_base_group_chat.py:472
"""
# Create the messages list if the task is a string or a chat message.
messages: List[BaseChatMessage] | None = None
if task is None:
pass
elif isinstance(task, str):
messages = [TextMessage(content=task, source="user")]
elif isinstance(task, BaseChatMessage):
messages = [task]
elif isinstance(task, list):
if not task:
raise ValueError("Task list cannot be empty.")
messages = []
for msg in task:
if not isinstance(msg, BaseChatMessage):
raise ValueError("All messages in task list must be valid BaseChatMessage types")
messages.append(msg)
else:
raise ValueError("Task must be a string, a BaseChatMessage, or a list of BaseChatMessage.")
# Check if the messages types are registered with the message factory.
if messages is not None:
for msg in messages:
if not self._message_factory.is_registered(msg.__class__):
raise ValueError(
f"Message type {msg.__class__} is not registered with the message factory. "
"Please register it with the message factory by adding it to the "
"custom_message_types list when creating the team."
)
if self._is_running:
raise ValueError("The team is already running, it cannot run again until it is stopped.")
self._is_running = True
if self._embedded_runtime:
# Start the embedded runtime.
assert isinstance(self._runtime, SingleThreadedAgentRuntime)
self._runtime.start()View on GitHub (pinned to 027ecf0a37)
Solutions
- Convert the value: strings pass through, dicts go through MessageFactory.create(), otherwise build TextMessage(content=str(value), source="user").
- Check the variable you are forwarding — often an upstream function returns a dict or object instead of the expected str/message.
- Pass None explicitly when there is no task.
Example fix
# before await team.run(task=result.json()) # dict -> ValueError # after await team.run(task=str(result.json())) # or TextMessage(content=..., source="user")
Defensive patterns
Strategy: type-guard
Validate before calling
from autogen_agentchat.messages import BaseChatMessage, TextMessage
def normalize_task(task):
if isinstance(task, str):
return [TextMessage(content=task, source="user")]
if isinstance(task, BaseChatMessage):
return [task]
if isinstance(task, list):
return [m if isinstance(m, BaseChatMessage) else TextMessage(content=str(m), source="user") for m in task]
return [TextMessage(content=str(task), source="user")] Type guard
def is_valid_task(task) -> bool:
return task is None or isinstance(task, (str, BaseChatMessage)) or (
isinstance(task, list) and task and all(isinstance(m, BaseChatMessage) for m in task)
) Prevention
- Always pass str, BaseChatMessage, list[BaseChatMessage], or None.
- Normalize upstream data (dicts, objects) into messages before calling run().
- Annotate helper APIs with the task union type so mypy catches misuse.
When it happens
Trigger: Calling team.run(task=42), team.run(task={'prompt': 'hi'}), or passing a BaseAgentEvent instance. Note task=None is valid and means 'no new task'.
Common situations: Passing a dict expecting it to be interpreted as a message; passing a variable whose type changed upstream; passing a ChatCompletion result object directly.
Related errors
- All messages in task list must be valid BaseChatMessage type
- Expected Memory, List[Memory], or None, got {type(memory)}
- Unsupported tool type: {type(tool)}
- Unsupported handoff type: {type(handoff)}
- Message type must be a string, got {type(message_type)}
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/2f357c042f6fc78d.
Report an issue: GitHub.