{"record":{"id":"3b5a131c3901fe18","repo":"can1357/oh-my-pi","slug":"proxy-returned-malformed-pr-file-payload","errorCode":null,"errorMessage":"proxy returned malformed pr_file payload","messagePattern":"proxy returned malformed pr_file payload","errorType":"exception","errorClass":"GitHubError","httpStatus":500,"severity":"error","filePath":"python/robomp/src/proxy_client.py","lineNumber":710,"sourceCode":"        created_at=str(data.get(\"created_at\") or \"\"),\n    )\n\n\ndef _pr_review_from(data: Any) -> PullRequestReviewInfo:\n    if not isinstance(data, dict):\n        raise GitHubError(500, \"proxy returned malformed pr_review payload\")\n    return PullRequestReviewInfo(\n        id=int(data.get(\"id\") or 0),\n        author=str(data.get(\"author\") or \"\"),\n        body=str(data.get(\"body\") or \"\"),\n        state=str(data.get(\"state\") or \"\"),\n        submitted_at=str(data.get(\"submitted_at\") or \"\"),\n    )\n\n\ndef _pr_file_from(data: Any) -> PullRequestFileInfo:\n    if not isinstance(data, dict):\n        raise GitHubError(500, \"proxy returned malformed pr_file payload\")\n    return PullRequestFileInfo(\n        path=str(data.get(\"path\") or \"\"),\n        status=str(data.get(\"status\") or \"\"),\n        additions=int(data.get(\"additions\") or 0),\n        deletions=int(data.get(\"deletions\") or 0),\n        patch=str(data.get(\"patch\") or \"\"),\n    )\n\n\ndef _pr_from(data: Any) -> PullRequestInfo:\n    if not isinstance(data, dict):\n        raise GitHubError(500, \"proxy returned malformed pr payload\")\n    return PullRequestInfo(\n        repo=str(data[\"repo\"]),\n        number=int(data[\"number\"]),\n        html_url=str(data[\"html_url\"]),\n        head_ref=str(data.get(\"head_ref\") or \"\"),\n        base_ref=str(data.get(\"base_ref\") or \"\"),","sourceCodeStart":692,"sourceCodeEnd":728,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/python/robomp/src/proxy_client.py#L692-L728","documentation":"GitHubError(500) raised by _pr_file_from when a PR file-diff payload from the proxy is not a JSON object. Each file entry (path, status, additions, deletions, patch) must be a dict; a non-dict element aborts the whole file listing.","triggerScenarios":"Calling list_pr_files() when the proxy returns the files array containing nulls/scalars, or a non-object body entirely (e.g. a bare list of path strings).","commonSituations":"Proxy serving a legacy flat path-list format for large PRs; null entries for binary files if the proxy mishandles them; proxy cache holding an outdated schema; version skew between proxy and client.","solutions":["Inspect the raw files response from the proxy and locate the non-object element.","Invalidate proxy caches of the PR file listing that may use a legacy format.","Upgrade/roll back the proxy so its file schema matches the client's.","Retry the call; if persistent, fall back to fetching the diff via the git layer (compare head/base refs) instead of the proxy.","Report the schema violation to the proxy maintainers."],"exampleFix":"# before\nfiles = client.list_pr_files(\"org/repo\", pr)  # GitHubError 500\n\n# after\ntry:\n    files = client.list_pr_files(\"org/repo\", pr)\nexcept GitHubError as e:\n    if e.status == 500:\n        files = diff_via_git(head_ref, base_ref)  # bypass proxy file listing\n    else:\n        raise","handlingStrategy":"fallback","validationCode":"raw = resp.json()\nfiles = raw if isinstance(raw, list) else []\nif any(not isinstance(f, dict) for f in files):\n    raise RuntimeError(\"proxy returned non-object pr_file entries\")","typeGuard":"def is_pr_file(data: object) -> bool:\n    return isinstance(data, dict) and \"path\" in data and \"status\" in data","tryCatchPattern":"try:\n    files = client.list_pr_files(\"org/repo\", pr)\nexcept GitHubError as e:\n    if e.status == 500 and \"malformed pr_file payload\" in str(e):\n        files = diff_via_git(head_ref, base_ref)  # bypass proxy file listing\n    else:\n        raise","preventionTips":["Keep a git-level diff fallback (compare head/base refs) for file listings.","Check the proxy's handling of binary files — a common source of null entries.","Invalidate proxy caches of file listings after proxy upgrades.","Validate file-list responses in CI for large PRs where truncation/legacy formats appear."],"tags":["proxy","payload-validation","pull-request","diff","github"],"backgroundTag":"proxy-malformed-payload","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}