can1357/oh-my-pi · error · GitHubError

proxy returned malformed comment payload

Error message

proxy returned malformed comment payload

What it means

GitHubError(500) raised by _comment_from when the proxy's comment payload is not a JSON object. list_comments expects each element and post_comment expects the created comment to be dicts with id/author/body; any other JSON type breaks the contract.

Source

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

        number=int(data["number"]),
        is_pull_request=bool(data.get("is_pull_request")),
        title=str(data.get("title") or ""),
        body=str(data.get("body") or ""),
        state=str(data.get("state") or ""),
        state_reason=str(data.get("state_reason") or ""),
        merged_at=str(data.get("merged_at") or ""),
        author=str(data.get("author") or ""),
        labels=tuple(str(x) for x in (data.get("labels") or [])),
        comments=int(data.get("comments") or 0),
        created_at=str(data.get("created_at") or ""),
        updated_at=str(data.get("updated_at") or ""),
        html_url=str(data.get("html_url") or ""),
    )


def _comment_from(data: Any) -> CommentInfo:
    if not isinstance(data, dict):
        raise GitHubError(500, "proxy returned malformed comment payload")
    return CommentInfo(
        id=int(data["id"]),
        author=str(data.get("author") or ""),
        body=str(data.get("body") or ""),
        created_at=str(data.get("created_at") or ""),
    )


def _reaction_from(data: Any) -> ReactionInfo:
    if not isinstance(data, dict):
        raise GitHubError(500, "proxy returned malformed reaction payload")
    return ReactionInfo(
        content=str(data.get("content") or ""),
        user_login=str(data.get("user_login") or ""),
        user_type=str(data.get("user_type") or ""),
    )

View on GitHub (pinned to 9690622007)

Solutions

  1. Inspect the raw proxy response for the comments endpoint to identify the non-dict body.
  2. For post_comment: check whether the proxy is configured for fire-and-forget mode and switch it to return the created object.
  3. Align proxy version with the client; redeploy if the response shape changed.
  4. Retry list_comments; on persistent failure, fetch comments via an alternate endpoint (e.g. get_issue and its embedded data).
  5. Report the malformed response to the proxy maintainers with the exact body.

Example fix

# before
comment = client.post_comment("org/repo", 42, "done")  # GitHubError 500

# after
try:
    comment = client.post_comment("org/repo", 42, "done")
except GitHubError as e:
    if e.status == 500:
        logging.warning("comment posted but proxy returned no object; verifying via list_comments")
        comment = next(c for c in client.list_comments("org/repo", 42) if c.body == "done")
    else:
        raise
Defensive patterns

Strategy: type-guard

Validate before calling

body = resp.json()
comments = body if isinstance(body, list) else []
if any(not isinstance(c, dict) for c in comments):
    raise RuntimeError("proxy returned non-object comment entries")

Type guard

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

Try / catch

try:
    comment = client.post_comment("org/repo", 42, "done")
except GitHubError as e:
    if e.status == 500 and "malformed comment payload" in str(e):
        comment = None  # verify via list_comments before re-posting
    else:
        raise

Prevention

When it happens

Trigger: Calling list_comments() with a non-object element in the comments array, or post_comment() when the proxy acknowledges the POST with a scalar/null instead of the created comment object.

Common situations: Proxy ACK-only mode returning "ok" or null on post_comment; deleted comment represented as null in a listing; proxy desync returning raw GitHub HTML/JSON scalar; middleware rewriting response bodies.

Understand the failure class

Related errors


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