can1357/oh-my-pi · error · ValueError
{field} must contain only strings
Error message
{field} must contain only strings What it means
After confirming the field is a list, `_tuple_of_strings` checks each element is a string. This error fires when at least one element is a number, bool, null, or nested structure; the parser aborts instead of returning a partially-converted tuple.
Source
Thrown at python/omp-rpc/src/omp_rpc/protocol.py:285
def _optional_float(payload: JsonObject, field: str) -> float | None:
value = payload.get(field)
if value is None:
return None
if isinstance(value, bool) or not isinstance(value, (int, float)):
raise ValueError(f"{field} must be a number")
return float(value)
def _tuple_of_strings(values: object, *, field: str) -> tuple[str, ...] | None:
if values is None:
return None
if not isinstance(values, list):
raise ValueError(f"{field} must be a list")
result: list[str] = []
for item in values:
if not isinstance(item, str):
raise ValueError(f"{field} must contain only strings")
result.append(item)
return tuple(result) or None
def _parse_agent_message(payload: JsonObject, *, field: str) -> AgentMessage:
_require_literal(
payload.get("role"), _AGENT_MESSAGE_ROLE_VALUES, field=f"{field}.role"
)
return cast(AgentMessage, _clone_json_object(payload, field=field))
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)
View on GitHub (pinned to 9690622007)
Solutions
- Map elements to strings before parsing: [str(x) for x in value] — verify str() preserves wire semantics (numeric enums may need a lookup table)
- Fix the producer so the list contains only JSON strings
- Drop None entries if they are placeholders: [x for x in value if x is not None]
Example fix
# before
payload = {"modes": ["text", 2]}
info = parse_model_info(payload) # ValueError: modes must contain only strings
# after
payload = {"modes": [str(x) for x in ["text", 2]]}
info = parse_model_info(payload) Defensive patterns
Strategy: validation
Validate before calling
def ensure_list_of_str(payload: dict, field: str) -> None:
value = payload.get(field)
if value is None:
return
if not isinstance(value, list):
raise TypeError(f"{field!r} must be a list")
for item in value:
if not isinstance(item, str):
raise TypeError(f"{field!r} contains non-string: {item!r}")
ensure_list_of_str(payload, "modes")
parse_model_info(payload) Type guard
def is_str_tuple(value: object) -> bool:
return isinstance(value, list) and all(isinstance(x, str) for x in value) Try / catch
try:
req = parse_extension_ui_request(payload)
except ValueError as e:
logger.error("string-list field had mixed types", extra={"payload": payload, "error": str(e)})
raise ProtocolError("malformed extension request") from e Prevention
- Enforce homogeneous string lists at the producer with typed models (list[str] annotations, pydantic)
- Filter or map None placeholders out before serialization
- Use string enums on the wire; map numeric enums at the producer boundary
- Round-trip fixture payloads through the parser in CI to catch drift
When it happens
Trigger: parse_model_info or parse_extension_ui_request receives a list field containing mixed types — e.g. ["text", 2] or [None] in a field like supported input modes or argument names.
Common situations: Numeric enum values sent where string enums are expected; a producer includes null placeholders in lists; mixed-type arrays from dynamically typed producer code.
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
- {field} must be a string
- {field} must be a boolean
- {field}[{index}] must be a string
- {field} must be a string or an array of strings
- {field} must be an integer
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/267c3c64c3d8b92b.
Report an issue: GitHub.