{"record":{"id":"0689e32c86e5c0cb","repo":"666ghj/MiroFish","slug":"github-graphql-returned-invalid-page-information","errorCode":null,"errorMessage":"GitHub GraphQL returned invalid page information","messagePattern":"GitHub GraphQL returned invalid page information","errorType":"exception","errorClass":"StarHistoryError","httpStatus":null,"severity":"error","filePath":"scripts/star_history.py","lineNumber":286,"sourceCode":"        if not isinstance(raw_edges, list):\n            raise StarHistoryError(\"GitHub GraphQL edges were not a list\")\n\n        edges: list[StargazerEdge] = []\n        for raw_edge in raw_edges:\n            if not isinstance(raw_edge, dict):\n                raise StarHistoryError(\"GitHub GraphQL returned an invalid edge\")\n            cursor = raw_edge.get(\"cursor\")\n            starred_at = raw_edge.get(\"starredAt\")\n            if not isinstance(cursor, str) or not cursor:\n                raise StarHistoryError(\"GitHub GraphQL returned an invalid edge cursor\")\n            if not isinstance(starred_at, str):\n                raise StarHistoryError(\"GitHub GraphQL returned an invalid star timestamp\")\n            edges.append(StargazerEdge(cursor, _parse_github_timestamp(starred_at)))\n\n        has_next_page = page_info.get(\"hasNextPage\")\n        end_cursor = page_info.get(\"endCursor\")\n        if type(has_next_page) is not bool:\n            raise StarHistoryError(\"GitHub GraphQL returned invalid page information\")\n        if end_cursor is not None and not isinstance(end_cursor, str):\n            raise StarHistoryError(\"GitHub GraphQL returned an invalid page cursor\")\n        if has_next_page and not end_cursor:\n            raise StarHistoryError(\"GitHub GraphQL omitted the next page cursor\")\n\n        return StargazerPage(\n            total_count=total_count,\n            edges=tuple(edges),\n            has_next_page=has_next_page,\n            end_cursor=end_cursor,\n            rate_remaining=rate_remaining,\n        )\n\n\ndef _strict_non_negative_int(value: Any, label: str) -> int:\n    if type(value) is not int or value < 0:\n        raise StarHistoryError(f\"{label} must be a non-negative integer\")\n    return value","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/666ghj/MiroFish/blob/b5b53acc57189a4a42e44a23e149dc655c98fe82/scripts/star_history.py#L268-L304","documentation":"pageInfo.hasNextPage was not exactly a bool (checked with type(...) is not bool, so 1/0/'true' are rejected too). The pagination loop decides whether to issue another request from this flag, so a non-bool raises StarHistoryError('GitHub GraphQL returned invalid page information').","triggerScenarios":"A response where pageInfo is missing hasNextPage (None), or a hand-crafted fixture that used 1/0, 'true'/'false', or the string 'True' instead of a JSON boolean.","commonSituations":"Test fixtures written in JSON with truthy integers; a stub server serializing Python bools as ints; the query dropping pageInfo { hasNextPage }.","solutions":["Ensure the query selects pageInfo { hasNextPage endCursor }","Fix fixtures to use real JSON booleans (true/false, not 1/0 or quoted strings)","Log page_info to see the raw value when it fires"],"exampleFix":"// before (fixture)\n\"pageInfo\": {\"hasNextPage\": 1}\n\n// after (fixture)\n\"pageInfo\": {\"hasNextPage\": true, \"endCursor\": \"abc\"}","handlingStrategy":"validation","validationCode":"page_info = payload[\"data\"][\"repository\"][\"stargazers\"].get(\"pageInfo\", {})\nif type(page_info.get(\"hasNextPage\")) is not bool:\n    raise StarHistoryError(\"pageInfo.hasNextPage missing or not a JSON boolean\")","typeGuard":"def page_info_is_valid(page_info: object) -> TypeGuard[dict]:\n    return (\n        isinstance(page_info, dict)\n        and type(page_info.get(\"hasNextPage\")) is bool\n        and (page_info.get(\"endCursor\") is None or isinstance(page_info[\"endCursor\"], str))\n    )","tryCatchPattern":"try:\n    page = _parse_graphql_page(payload)\nexcept StarHistoryError as exc:\n    if \"invalid page information\" in str(exc):\n        raise StarHistoryError(\"cannot decide whether more pages exist; halting pagination\") from exc\n    raise","preventionTips":["Always request pageInfo { hasNextPage endCursor } in paginated queries","Use real JSON booleans in fixtures — 1/0 and 'true' are rejected by strict type checks"],"tags":["github-api","graphql","pagination","validation","star-history"],"backgroundTag":null,"analyzedSha":"b5b53acc57189a4a42e44a23e149dc655c98fe82","analyzedAt":"2026-08-14T22:29:33.146Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}