can1357/oh-my-pi · error · ValueError
{field} must be a string
Error message
{field} must be a string What it means
omp-rpc's protocol parser validates every field of an incoming JSON payload before constructing typed objects. `_require_str` throws this ValueError when a required field named `{field}` is missing or is not a JSON string. The library fails fast so malformed payloads surface at parse time instead of causing type errors deep in application code.
Source
Thrown at python/omp-rpc/src/omp_rpc/protocol.py:206
def _require_literal(value: object, allowed: frozenset[str], *, field: str) -> str:
if not isinstance(value, str) or value not in allowed:
expected = ", ".join(sorted(allowed))
raise ValueError(f"{field} must be one of: {expected}")
return value
def _optional_literal(
value: object, allowed: frozenset[str], *, field: str
) -> str | None:
if value is None:
return None
return _require_literal(value, allowed, field=field)
def _require_str(payload: JsonObject, field: str) -> str:
value = payload.get(field)
if not isinstance(value, str):
raise ValueError(f"{field} must be a string")
return value
def _require_bool(payload: JsonObject, field: str) -> bool:
value = payload.get(field)
if not isinstance(value, bool):
raise ValueError(f"{field} must be a boolean")
return value
def _optional_str(payload: JsonObject, field: str) -> str | None:
value = payload.get(field)
if value is None:
return None
if not isinstance(value, str):
raise ValueError(f"{field} must be a string")
return value
View on GitHub (pinned to 9690622007)
Solutions
- Log/print the full payload and check the named field's actual JSON type before calling the parser
- Coerce or fix the value to a string (str(value) or correct the producer)
- If the field is legitimately absent, use the optional variant or supply a default before parsing
- Pin both client and server to compatible omp-rpc versions so the wire schema matches
Example fix
# before
payload = {"id": 42, "name": "bash"}
info = parse_tool_descriptor(payload) # ValueError: id must be a string
# after
payload = {"id": str(42), "name": "bash"}
info = parse_tool_descriptor(payload) Defensive patterns
Strategy: validation
Validate before calling
def ensure_str(payload: dict, field: str) -> None:
value = payload.get(field)
if not isinstance(value, str):
raise TypeError(f"{field!r} must be a string, got {type(value).__name__}: {value!r}")
# before parsing:
ensure_str(payload, "id")
parse_tool_descriptor(payload) Type guard
def is_str_field(payload: dict, field: str) -> bool:
return isinstance(payload.get(field), str) Try / catch
try:
info = parse_tool_descriptor(payload)
except ValueError as e:
logger.error("invalid tool descriptor payload", extra={"payload": payload, "error": str(e)})
raise ProtocolError("malformed tool descriptor") from e Prevention
- Validate payloads against the protocol schema at the boundary before parsing
- Keep client and omp-rpc versions in lockstep with the server
- Never hand-build IDs or names as numbers; stringify at production time
- Log the raw payload on parse failure to speed diagnosis
When it happens
Trigger: Calling parse_model_info, parse_tool_descriptor, parse_todo_item, parse_todo_phase, parse_session_state, or _parse_thinking_config with a payload whose required field is absent (None), a number, bool, list, or dict instead of a string — e.g. a deserialized RPC response missing `id` or carrying `id: 123` instead of `"123"`.
Common situations: A server upgraded and renamed/retyped a field; a hand-built fixture or mock response uses a numeric ID; JSON was produced by a non-Python serializer that emits unquoted values; a partially-constructed dict was passed to the parser.
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 boolean
- {field}[{index}] must be a string
- {field} must be a string or an array of strings
- {field} must be an integer
- {field} must be a number
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/3443313a66f0dcd7.
Report an issue: GitHub.