agentscope-ai/agentscope · error · TypeError
Input must be a list of Msg objects.
Error message
Input must be a list of Msg objects.
What it means
The formatter base class validates that input is strictly a Python list of Msg objects; passing a single Msg, a tuple, a generator, or a list containing anything else raises this TypeError. It is a precondition check in assert_list_of_msgs, called by format()/_format_messages(). The library requires this exact shape because it iterates and formats each Msg.
Source
Thrown at src/agentscope/formatter/_formatter_base.py:61
for t in self.input_types
if t not in ("text/plain", "application/x-thinking")
]
@abstractmethod
async def format(self, *args: Any, **kwargs: Any) -> list[dict[str, Any]]:
"""Format the Msg objects to a list of dictionaries that satisfy the
API requirements."""
@staticmethod
def assert_list_of_msgs(msgs: list[Msg]) -> None:
"""Assert that the input is a list of Msg objects.
Args:
msgs (`list[Msg]`):
A list of Msg objects to be validated.
"""
if not isinstance(msgs, list):
raise TypeError("Input must be a list of Msg objects.")
for msg in msgs:
if not isinstance(msg, Msg):
raise TypeError(
f"Expected Msg object, got {type(msg)} instead.",
)
@staticmethod
def _convert_unsupported_data_block_to_string(block: DataBlock) -> str:
"""Convert an unsupported data block into its textual fallback.
URL sources remain accessible through their URL. Base64 sources are
persisted to a temporary file so the model can still reference the
result when the target API cannot carry that media type directly.
Args:
block (`DataBlock`):
The unsupported data block to convert.View on GitHub (pinned to e90f1c7592)
Solutions
- Wrap a single message in a list: formatter.format([msg])
- If msgs is a generator/tuple, convert with list(msgs)
- Ensure every element is a Msg instance (reconstruct from dicts via Msg.from_dict or similar if deserializing)
Example fix
# before formatter.format(msg) # after formatter.format([msg])
Defensive patterns
Strategy: validation
Validate before calling
msgs = [msg] if isinstance(msg, Msg) else msgs assert isinstance(msgs, list), "formatter.format expects list[Msg]"
Type guard
def is_msg_list(msgs) -> bool:
return isinstance(msgs, list) and all(isinstance(m, Msg) for m in msgs) Try / catch
try:
formatter.format(msgs)
except TypeError as e:
if "list of Msg" in str(e):
msgs = [msg] if not isinstance(msgs, list) else list(msgs)
formatted = formatter.format(msgs)
else:
raise Prevention
- Always call format() with a list literal, even for one message
- Convert generators/tuples with list() before formatting
When it happens
Trigger: Calling formatter.format(single_msg) instead of format([single_msg]); passing msgs=conversation.messages when it's a tuple/generator; passing a list of dicts or strings.
Common situations: Reusing code written for APIs that accept a single message; wrapping history in a tuple or generator comprehension; feeding raw dicts from a serialized conversation.
Understand the failure class
Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.
Related errors
- Expected Msg object, got {type(msg)} instead.
- Input validation failed for tool '{tool_call.name}': {e.mess
- The injection template must contain the '{runtime_state}' pl
- Expected a 5-field cron expression, got {record.data.cron_ex
- Unsupported audio source type: {type(source)}
AI-assisted analysis of agentscope-ai/agentscope@e90f1c7592 (2026-08-28).
Data as JSON: /api/errors/ae00082cfd880014.
Report an issue: GitHub.