can1357/oh-my-pi · error · ValueError
messages must be a list
Error message
messages must be a list
What it means
parse_agent_messages expects a JSON array of agent messages (or null, meaning empty). It raises this error when the payload is any other JSON type (object, string, number, bool). The library throws so the following per-item loop can safely index and parse each element.
Source
Thrown at python/omp-rpc/src/omp_rpc/protocol.py:315
def _parse_assistant_message(payload: JsonObject, *, field: str) -> AssistantMessage:
message = _parse_agent_message(payload, field=field)
if message.get("role") != "assistant":
raise ValueError(f"{field}.role must be 'assistant'")
return cast(AssistantMessage, message)
def _parse_tool_result_message(payload: JsonObject, *, field: str) -> ToolResultMessage:
message = _parse_agent_message(payload, field=field)
if message.get("role") != "toolResult":
raise ValueError(f"{field}.role must be 'toolResult'")
return cast(ToolResultMessage, message)
def parse_agent_messages(payload: JsonValue | None) -> tuple[AgentMessage, ...]:
if payload is None:
return ()
if not isinstance(payload, list):
raise ValueError("messages must be a list")
messages: list[AgentMessage] = []
for index, item in enumerate(payload):
messages.append(
_parse_agent_message(
_clone_json_object(item, field=f"messages[{index}]"),
field=f"messages[{index}]",
)
)
return tuple(messages)
def parse_assistant_message_event(payload: JsonObject) -> AssistantMessageEvent:
event_type = _require_literal(
payload.get("type"),
_ASSISTANT_MESSAGE_EVENT_TYPE_VALUES,
field="assistantMessageEvent.type",
)View on GitHub (pinned to 9690622007)
Solutions
- Unwrap the payload to the actual list before calling (e.g. payload["messages"])
- Wrap a single message in a list: [message]
- Check the server response shape against the protocol docs and fix the emitter or the extraction point
- Handle null explicitly if absence should mean empty
Example fix
// before parse_agent_messages(result["messages"]) // after parse_agent_messages(result)
Defensive patterns
Strategy: validation
Validate before calling
if payload is not None and not isinstance(payload, list):
raise TypeError("expected a list of messages (or None)") Type guard
from typing import TypeGuard
def is_message_list(v: object) -> TypeGuard[list]:
return isinstance(v, list) Try / catch
try:
messages = parse_agent_messages(payload)
except ValueError:
messages = () # or unwrap payload["messages"] and retry Prevention
- Confirm the RPC response field is the bare array, not an envelope object
- Treat None as an empty message list
- Validate response shape once at the transport layer
When it happens
Trigger: Calling parse_agent_messages with a single message object instead of a list; a server returning a wrapped object like {"messages": [...]} instead of the bare array; passing a dict from an RPC response field that should have been an array.
Common situations: Passing response['messages'] vs response directly; older server versions returning a different envelope; hand-constructed payloads in tests.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- rpc frame must be an object
- request must be an object
- Replacement text is not valid UTF-8: {err}
- OMP_AUTH_BROKER_ACCOUNT_POOL_FILE contains an empty provider
- OMP_AUTH_BROKER_ACCOUNT_POOL_FILE contains a provider id wit
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/bfdc37c3b9548f91.
Report an issue: GitHub.