{"record":{"id":"53f2d274581f2dce","repo":"can1357/oh-my-pi","slug":"proxy-returned-malformed-reaction-payload","errorCode":null,"errorMessage":"proxy returned malformed reaction payload","messagePattern":"proxy returned malformed reaction payload","errorType":"exception","errorClass":"GitHubError","httpStatus":500,"severity":"error","filePath":"python/robomp/src/proxy_client.py","lineNumber":674,"sourceCode":"        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\ndef _review_comment_from(data: Any) -> ReviewCommentInfo:\n    if not isinstance(data, dict):\n        raise GitHubError(500, \"proxy returned malformed review_comment payload\")\n    line = data.get(\"line\")\n    return ReviewCommentInfo(\n        id=int(data.get(\"id\") or 0),\n        author=str(data.get(\"author\") or \"\"),\n        body=str(data.get(\"body\") or \"\"),\n        path=str(data.get(\"path\") or \"\"),\n        line=line if isinstance(line, int) else None,\n        created_at=str(data.get(\"created_at\") or \"\"),","sourceCodeStart":656,"sourceCodeEnd":692,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/python/robomp/src/proxy_client.py#L656-L692","documentation":"GitHubError(500) raised by _reaction_from when a reaction payload from the proxy is not a JSON object. Each reaction must be a dict (content, user_login, user_type); non-dict entries abort the whole reaction listing.","triggerScenarios":"Calling list_comment_reactions() when the proxy returns scalars or nulls inside the reactions array instead of reaction objects.","commonSituations":"Proxy serialization bug for reactions by ghost/deleted users (emitted as null); legacy flat-string reaction format from an old proxy cache; version skew between proxy and client schema.","solutions":["Inspect the raw reactions response from the proxy to find the non-object element.","Refresh/invalidate proxy caches that may hold the legacy reaction format.","Update the proxy to the client-compatible version and redeploy.","Retry the call; if it persists, skip reaction data (treat as empty) with a logged warning.","Report the schema violation to the proxy maintainers."],"exampleFix":"# before\nreactions = client.list_comment_reactions(\"org/repo\", 42, comment_id)\n\n# after\ntry:\n    reactions = client.list_comment_reactions(\"org/repo\", 42, comment_id)\nexcept GitHubError as e:\n    if e.status == 500:\n        reactions = []  # degrade gracefully; reactions are non-critical\n    else:\n        raise","handlingStrategy":"fallback","validationCode":"raw = resp.json()\nif any(not isinstance(r, dict) for r in (raw if isinstance(raw, list) else [])):\n    raise RuntimeError(\"non-object reaction entries in proxy response\")","typeGuard":"def is_reaction_payload(data: object) -> bool:\n    return isinstance(data, dict) and \"content\" in data","tryCatchPattern":"try:\n    reactions = client.list_comment_reactions(\"org/repo\", 42, cid)\nexcept GitHubError as e:\n    if e.status == 500 and \"malformed reaction payload\" in str(e):\n        reactions = []  # reactions are non-critical\n    else:\n        raise","preventionTips":["Treat reactions as optional data — degrade to empty rather than failing the workflow.","Check the proxy for null serialization of reactions from deleted/ghost users.","Refresh proxy caches that may hold a legacy flat reaction format.","Include reaction endpoints in proxy contract tests."],"tags":["proxy","payload-validation","reactions","github"],"backgroundTag":"proxy-malformed-payload","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}