OpenBMB/ChatDev · error · ValueError
message payload must be a list
Error message
message payload must be a list
What it means
deserialize_messages expects the JSON string payload to decode to a top-level JSON array of message objects. If json.loads yields a dict (single message or {"messages": [...]}), a string, or a number, ValueError is raised.
Source
Thrown at entity/messages.py:410
metadata=data.get("metadata") or {},
tool_calls=tool_calls,
keep=bool(data.get("keep", False)),
preserve_role=bool(data.get("preserve_role", False)),
)
def serialize_messages(messages: List[Message], *, include_data: bool = True) -> str:
"""Serialize message list into JSON string."""
return json.dumps([msg.to_dict(include_data=include_data) for msg in messages], ensure_ascii=False)
def deserialize_messages(payload: str) -> List[Message]:
"""Deserialize JSON string back to messages."""
if not payload:
return []
raw = json.loads(payload)
if not isinstance(raw, list):
raise ValueError("message payload must be a list")
return [Message.from_dict(item) for item in raw if isinstance(item, dict)]
def _copy_content(content: MessageContent) -> MessageContent:
if content is None:
return None
if isinstance(content, str):
return content
copied: List[Any] = []
for block in content:
if isinstance(block, MessageBlock):
copied.append(block.copy())
else:
copied.append(copy.deepcopy(block))
return copied
View on GitHub (pinned to 4fb2db0ea9)
Solutions
- Ensure the payload is a JSON array: json.dumps(list_of_message_dicts)
- If you have a single message, wrap it: json.dumps([msg_dict])
- Unwrap envelopes first: payload = resp["messages"] then serialize/deserialize consistently
Example fix
# before deserialize_messages(json.dumps(msg_dict)) # after deserialize_messages(json.dumps([msg_dict]))
Defensive patterns
Strategy: type-guard
Validate before calling
import json
raw = json.loads(payload)
if isinstance(raw, dict):
payload = json.dumps(raw.get("messages", [raw])) Type guard
def is_message_list_payload(payload: str) -> bool:
try:
return isinstance(json.loads(payload), list)
except Exception:
return False Try / catch
try:
msgs = deserialize_messages(payload)
except ValueError:
raw = json.loads(payload)
msgs = [Message.from_dict(m) for m in (raw["messages"] if isinstance(raw, dict) else [raw])] Prevention
- Standardize on serialize_messages output (a JSON array)
- Never wrap stored payloads in envelopes
When it happens
Trigger: deserialize_messages(json.dumps(single_message_dict)); passing a payload like "{\"messages\": [...]}" produced by another serializer; double-encoded JSON strings.
Common situations: Round-trip mismatch: one code path stores serialize_messages' list output, another stores a bare message; API responses wrapping messages in an envelope.
Related errors
- message dict missing role
- No node types registered; cannot validate workflow
- Unsupported node type '{ntype}' for node '{nid}'. Only {allo
- Design file not found: {config_path}
- YAML root must be a mapping
AI-assisted analysis of OpenBMB/ChatDev@4fb2db0ea9 (2026-08-27).
Data as JSON: /api/errors/08e93e05148d9c74.
Report an issue: GitHub.