{"record":{"id":"b70d95d4fce06d2e","repo":"can1357/oh-my-pi","slug":"proxy-returned-malformed-issue-index-payload","errorCode":null,"errorMessage":"proxy returned malformed issue index payload","messagePattern":"proxy returned malformed issue index payload","errorType":"exception","errorClass":"GitHubError","httpStatus":500,"severity":"error","filePath":"python/robomp/src/proxy_client.py","lineNumber":642,"sourceCode":"    return IssueSummary(\n        repo=str(data[\"repo\"]),\n        number=int(data[\"number\"]),\n        title=str(data.get(\"title\") or \"\"),\n        state=str(data.get(\"state\") 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        updated_at=str(data.get(\"updated_at\") or \"\"),\n        created_at=str(data.get(\"created_at\") or \"\"),\n        html_url=str(data.get(\"html_url\") or \"\"),\n        state_reason=str(data.get(\"state_reason\") or \"\"),\n        is_pull_request=bool(data.get(\"is_pull_request\")),\n    )\n\n\ndef _index_entry_from(data: Any) -> IssueIndexEntry:\n    if not isinstance(data, dict):\n        raise GitHubError(500, \"proxy returned malformed issue index payload\")\n    return IssueIndexEntry(\n        repo=str(data[\"repo\"]),\n        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","sourceCodeStart":624,"sourceCodeEnd":660,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/python/robomp/src/proxy_client.py#L624-L660","documentation":"GitHubError(500) raised by _index_entry_from when an entry in the proxy's issue-index response is not a JSON object. Every index entry must be a dict (repo/number/is_pull_request at minimum); a non-dict entry means the proxy violated its index schema.","triggerScenarios":"Calling list_issue_index_entries() when the proxy returns the index as raw scalars, a flat list of strings/numbers, or an array containing null entries instead of objects.","commonSituations":"Proxy serving an outdated index format (pre-objects flat list); cache layer returning a stale/legacy serialized index; proxy bug when an issue is deleted from the index leaving null placeholders; version skew between proxy and client.","solutions":["Fetch the index endpoint directly from the proxy and confirm each element is a JSON object.","Invalidate/refresh any proxy-side cache of the index that may hold a legacy format.","Align proxy version with the client schema — redeploy the proxy if it predates the index-object format.","Retry the call; if persistent, fall back to list_issues() and build the index client-side.","Report/patch the proxy so deleted entries are omitted rather than emitted as null."],"exampleFix":"# before\nentries = client.list_issue_index_entries(\"org/repo\")  # GitHubError 500\n\n# after\ntry:\n    entries = client.list_issue_index_entries(\"org/repo\")\nexcept GitHubError as e:\n    if e.status == 500:\n        entries = rebuild_index_from_list(client.list_issues(\"org/repo\"))\n    else:\n        raise","handlingStrategy":"validation","validationCode":"raw = resp.json()\nif not isinstance(raw, list) or not all(isinstance(e, dict) for e in raw):\n    raise RuntimeError(\"proxy issue index must be a list of objects\")","typeGuard":"def is_index_entry(data: object) -> bool:\n    return isinstance(data, dict) and \"repo\" in data and \"number\" in data","tryCatchPattern":"try:\n    entries = client.list_issue_index_entries(\"org/repo\")\nexcept GitHubError as e:\n    if e.status == 500 and \"malformed issue index\" in str(e):\n        entries = rebuild_index_from_issues(client.list_issues(\"org/repo\"))\n    else:\n        raise","preventionTips":["Invalidate proxy index caches when upgrading the proxy schema.","Ensure the proxy omits deleted issues rather than emitting null placeholders.","Smoke-test the index endpoint after every proxy deploy.","Maintain a client-side index fallback built from list_issues."],"tags":["proxy","payload-validation","index","github"],"backgroundTag":"proxy-malformed-payload","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}