can1357/oh-my-pi · error · HTTPException
missing/invalid 'comments'
Error message
missing/invalid 'comments'
What it means
`_require_review_comments` validates the `comments` array of a PR review submission. `comments` must be a JSON array (null is tolerated and becomes []); a non-array value raises this HTTP 400. Individual element validation produces the more specific comments[idx] errors instead.
Source
Thrown at python/robomp/src/proxy/server.py:184
return None
if not isinstance(value, int) or isinstance(value, bool) or not (0 < value < 65536):
raise HTTPException(400, "missing/invalid 'slot_uid'")
return value
def _optional_str_list(value: Any, field: str) -> list[str] | None:
if value is None:
return None
if not isinstance(value, list) or not all(isinstance(v, str) for v in value):
raise HTTPException(400, f"invalid '{field}': must be array of strings")
return list(value)
def _require_review_comments(value: Any) -> list[dict[str, Any]]:
if value is None:
return []
if not isinstance(value, list):
raise HTTPException(400, "missing/invalid 'comments'")
comments: list[dict[str, Any]] = []
for idx, item in enumerate(value):
if not isinstance(item, dict):
raise HTTPException(400, f"comments[{idx}] must be an object")
path = _require_str(item.get("path"), f"comments[{idx}].path")
line = _require_int(item.get("line"), f"comments[{idx}].line")
body = _require_str(item.get("body"), f"comments[{idx}].body")
side = str(item.get("side") or "RIGHT")
if side not in ("RIGHT", "LEFT"):
raise HTTPException(400, f"comments[{idx}].side must be RIGHT or LEFT")
comment: dict[str, Any] = {"path": path, "line": line, "side": side, "body": body}
start_line = item.get("start_line")
if start_line is not None:
comment["start_line"] = _require_int(start_line, f"comments[{idx}].start_line")
start_side = item.get("start_side")
if start_side is not None:
start_side_str = _require_str(start_side, f"comments[{idx}].start_side")
if start_side_str not in ("RIGHT", "LEFT"):View on GitHub (pinned to 9690622007)
Solutions
- Wrap the comment payload in an array: [{"path": ..., "line": ..., "body": ...}].
- If the value is a JSON string, parse it client-side before posting.
- Omit `comments` entirely (or send null) for review verdicts without comments — null is accepted.
- Inspect the request body with a debugger/logging middleware to confirm the actual encoded type.
Example fix
// before
{"event": "COMMENT", "comments": {"path": "a.py", "line": 3, "body": "fix"}}
// after
{"event": "COMMENT", "comments": [{"path": "a.py", "line": 3, "body": "fix"}]} Defensive patterns
Strategy: type-guard
Validate before calling
comments = raw if isinstance(raw, list) else ([raw] if isinstance(raw, dict) else None)
if comments is None:
raise ValueError("comments must be a list of comment objects") Type guard
def is_comment_list(v: object) -> TypeGuard[list[dict]]:
return isinstance(v, list) and all(isinstance(x, dict) for x in v) Try / catch
try:
resp = http.post(f"{base}/pr/{n}/review", json=payload)
resp.raise_for_status()
except httpx.HTTPStatusError as e:
if e.response.status_code == 400 and "'comments'" in e.response.text:
raise ValueError("comments must be a JSON array, not " + type(payload['comments']).__name__) from e
raise Prevention
- Never JSON-encode comments twice; post the parsed structure
- Wrap single comment objects in a list at the call site
- Model the review payload with pydantic so arrays are enforced locally
- When re-posting data from a GET response, rebuild the payload explicitly
When it happens
Trigger: Calling submit_pr_review with `comments` as an object, a string, or a number — e.g. sending a single comment object directly instead of wrapping it in a list, or sending comments as a JSON-encoded string.
Common situations: Clients double-encoding comments (JSON string inside JSON); SDK misuse where a single-comment convenience path forgets the array wrapper; copying a comments object from a GET response and posting it back unmodified.
Related errors
- comments[{idx}] must be an object
- missing/invalid 'slot_uid'
- invalid '{field}': must be array of strings
- comments[{idx}].side must be RIGHT or LEFT
- comments[{idx}].start_side must be RIGHT or LEFT
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/76a1179cf957261a.
Report an issue: GitHub.