{"record":{"id":"e89693314018ead2","repo":"can1357/oh-my-pi","slug":"proxy-returned-malformed-comment-payload","errorCode":null,"errorMessage":"proxy returned malformed comment payload","messagePattern":"proxy returned malformed comment payload","errorType":"exception","errorClass":"GitHubError","httpStatus":500,"severity":"error","filePath":"python/robomp/src/proxy_client.py","lineNumber":663,"sourceCode":"        number=int(data[\"number\"]),\n        is_pull_request=bool(data.get(\"is_pull_request\")),\n        title=str(data.get(\"title\") or \"\"),\n        body=str(data.get(\"body\") or \"\"),\n        state=str(data.get(\"state\") or \"\"),\n        state_reason=str(data.get(\"state_reason\") or \"\"),\n        merged_at=str(data.get(\"merged_at\") or \"\"),\n        author=str(data.get(\"author\") or \"\"),\n        labels=tuple(str(x) for x in (data.get(\"labels\") or [])),\n        comments=int(data.get(\"comments\") or 0),\n        created_at=str(data.get(\"created_at\") or \"\"),\n        updated_at=str(data.get(\"updated_at\") or \"\"),\n        html_url=str(data.get(\"html_url\") or \"\"),\n    )\n\n\ndef _comment_from(data: Any) -> CommentInfo:\n    if not isinstance(data, dict):\n        raise GitHubError(500, \"proxy returned malformed comment payload\")\n    return CommentInfo(\n        id=int(data[\"id\"]),\n        author=str(data.get(\"author\") or \"\"),\n        body=str(data.get(\"body\") or \"\"),\n        created_at=str(data.get(\"created_at\") or \"\"),\n    )\n\n\ndef _reaction_from(data: Any) -> ReactionInfo:\n    if not isinstance(data, dict):\n        raise GitHubError(500, \"proxy returned malformed reaction payload\")\n    return ReactionInfo(\n        content=str(data.get(\"content\") or \"\"),\n        user_login=str(data.get(\"user_login\") or \"\"),\n        user_type=str(data.get(\"user_type\") or \"\"),\n    )\n\n","sourceCodeStart":645,"sourceCodeEnd":681,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/python/robomp/src/proxy_client.py#L645-L681","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect the raw proxy response for the comments endpoint to identify the non-dict body.","For post_comment: check whether the proxy is configured for fire-and-forget mode and switch it to return the created object.","Align proxy version with the client; redeploy if the response shape changed.","Retry list_comments; on persistent failure, fetch comments via an alternate endpoint (e.g. get_issue and its embedded data).","Report the malformed response to the proxy maintainers with the exact body."],"exampleFix":"# before\ncomment = client.post_comment(\"org/repo\", 42, \"done\")  # GitHubError 500\n\n# after\ntry:\n    comment = client.post_comment(\"org/repo\", 42, \"done\")\nexcept GitHubError as e:\n    if e.status == 500:\n        logging.warning(\"comment posted but proxy returned no object; verifying via list_comments\")\n        comment = next(c for c in client.list_comments(\"org/repo\", 42) if c.body == \"done\")\n    else:\n        raise","handlingStrategy":"type-guard","validationCode":"body = resp.json()\ncomments = body if isinstance(body, list) else []\nif any(not isinstance(c, dict) for c in comments):\n    raise RuntimeError(\"proxy returned non-object comment entries\")","typeGuard":"def is_comment_payload(data: object) -> bool:\n    return isinstance(data, dict) and \"id\" in data","tryCatchPattern":"try:\n    comment = client.post_comment(\"org/repo\", 42, \"done\")\nexcept GitHubError as e:\n    if e.status == 500 and \"malformed comment payload\" in str(e):\n        comment = None  # verify via list_comments before re-posting\n    else:\n        raise","preventionTips":["Never blind-retry post_comment on this error — the comment may have been created; verify via list_comments.","Disable ACK-only mode on the proxy if it does not return created objects.","Validate comment responses in an integration test against the CommentInfo schema.","Log the raw body on failure to distinguish proxy bugs from gateway rewrites."],"tags":["proxy","payload-validation","comments","github"],"backgroundTag":"proxy-malformed-payload","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}