can1357/oh-my-pi · error · GitHubError

proxy returned malformed pr_review payload

Error message

proxy returned malformed pr_review payload

What it means

GitHubError(500) raised by _pr_review_from when a PR review payload from the proxy is not a JSON object. list_pr_reviews expects each review to be a dict and submit_pr_review expects the resulting review object; non-dict responses violate the proxy contract.

Source

Thrown at python/robomp/src/proxy_client.py:698


def _review_comment_from(data: Any) -> ReviewCommentInfo:
    if not isinstance(data, dict):
        raise GitHubError(500, "proxy returned malformed review_comment payload")
    line = data.get("line")
    return ReviewCommentInfo(
        id=int(data.get("id") or 0),
        author=str(data.get("author") or ""),
        body=str(data.get("body") or ""),
        path=str(data.get("path") or ""),
        line=line if isinstance(line, int) else None,
        created_at=str(data.get("created_at") or ""),
    )


def _pr_review_from(data: Any) -> PullRequestReviewInfo:
    if not isinstance(data, dict):
        raise GitHubError(500, "proxy returned malformed pr_review payload")
    return PullRequestReviewInfo(
        id=int(data.get("id") or 0),
        author=str(data.get("author") or ""),
        body=str(data.get("body") or ""),
        state=str(data.get("state") or ""),
        submitted_at=str(data.get("submitted_at") or ""),
    )


def _pr_file_from(data: Any) -> PullRequestFileInfo:
    if not isinstance(data, dict):
        raise GitHubError(500, "proxy returned malformed pr_file payload")
    return PullRequestFileInfo(
        path=str(data.get("path") or ""),
        status=str(data.get("status") or ""),
        additions=int(data.get("additions") or 0),
        deletions=int(data.get("deletions") or 0),
        patch=str(data.get("patch") or ""),

View on GitHub (pinned to 9690622007)

Solutions

  1. Inspect the raw proxy response for the PR reviews endpoint to see the actual non-dict body.
  2. For submit_pr_review: verify whether the review was actually created on GitHub, then re-fetch via list_pr_reviews instead of resubmitting.
  3. Align the proxy version with the client; redeploy if schemas diverge.
  4. Retry the listing; on persistent failure fall back to the GitHub web/API view of reviews.
  5. Report the contract violation to the proxy maintainers with the response body.

Example fix

# before
review = client.submit_pr_review("org/repo", pr, "APPROVE", "lgtm")  # GitHubError 500

# after
try:
    review = client.submit_pr_review("org/repo", pr, "APPROVE", "lgtm")
except GitHubError as e:
    if e.status == 500:
        reviews = client.list_pr_reviews("org/repo", pr)  # verify it landed
        review = reviews[-1] if reviews else None
    else:
        raise
Defensive patterns

Strategy: try-catch

Validate before calling

raw = resp.json()
if not isinstance(raw, dict):
    raise RuntimeError(f"proxy review payload not an object: {raw!r}")

Type guard

def is_pr_review(data: object) -> bool:
    return isinstance(data, dict) and "state" in data

Try / catch

try:
    review = client.submit_pr_review("org/repo", pr, "APPROVE")
except GitHubError as e:
    if e.status == 500 and "malformed pr_review payload" in str(e):
        reviews = client.list_pr_reviews("org/repo", pr)  # verify it landed; do not resubmit blindly
        review = reviews[-1] if reviews else None
    else:
        raise

Prevention

When it happens

Trigger: Calling list_pr_reviews() with a non-object element in the reviews array, or submit_pr_review() when the proxy acknowledges the review submission with null/a scalar instead of a PullRequestReviewInfo object.

Common situations: Proxy in ACK-only mode after submitting a review; null entries for pending/discarded reviews in a listing; proxy version skew changing the review envelope; body-rewriting middleware.

Understand the failure class

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/5cab0d8d272587ac. Report an issue: GitHub.