{"record":{"id":"37b2b6881357d203","repo":"666ghj/MiroFish","slug":"github-graphql-returned-no-pages","errorCode":null,"errorMessage":"GitHub GraphQL returned no pages","messagePattern":"GitHub GraphQL returned no pages","errorType":"exception","errorClass":"StarHistoryError","httpStatus":null,"severity":"error","filePath":"scripts/star_history.py","lineNumber":607,"sourceCode":"                raise StarHistoryError(\"GitHub GraphQL repeated an edge cursor\")\n            seen_edge_cursors.add(edge.cursor)\n            if edge.starred_at.date() < normalized_now.date():\n                daily_increments[edge.starred_at.date()] += 1\n\n        if page.end_cursor is not None:\n            if page.end_cursor in seen_page_cursors:\n                raise StarHistoryError(\"GitHub GraphQL repeated a page cursor\")\n            seen_page_cursors.add(page.end_cursor)\n        if not page.has_next_page:\n            break\n        if page.end_cursor is None:\n            raise StarHistoryError(\"GitHub GraphQL omitted the next page cursor\")\n        after = page.end_cursor\n        if page_number > 10_000:\n            raise StarHistoryError(\"GitHub GraphQL exceeded the page safety limit\")\n\n    if initial_total is None:\n        raise StarHistoryError(\"GitHub GraphQL returned no pages\")\n    if len(seen_edge_cursors) != initial_total:\n        raise StarHistoryError(\"stargazer list changed or was incomplete during backfill\")\n\n    running = 0\n    daily: list[dict[str, Any]] = []\n    for point_day in sorted(daily_increments):\n        running += daily_increments[point_day]\n        daily.append({\"date\": point_day.isoformat(), \"stars\": running})\n\n    state: dict[str, Any] = {\n        \"schema_version\": 1,\n        \"repository\": REPOSITORY,\n        \"timezone\": \"UTC\",\n        \"ongoing_interval_days\": INTERVAL_DAYS,\n        \"reconstruction\": {\n            \"method\": \"current_stargazers_starred_at\",\n            \"generated_at\": _format_state_timestamp(normalized_now),\n            \"daily\": daily,","sourceCodeStart":589,"sourceCodeEnd":625,"githubUrl":"https://github.com/666ghj/MiroFish/blob/b5b53acc57189a4a42e44a23e149dc655c98fe82/scripts/star_history.py#L589-L625","documentation":"Raised at scripts/star_history.py:607 immediately after the backfill pagination loop: if `initial_total` is still None, the `while True` loop never completed even one `github.fetch_stargazer_page()` call that reached the total-count assignment. It is a defensive assertion that should be unreachable in practice (the loop always executes at least once or raises earlier), guarding against control-flow regressions.","triggerScenarios":"Structurally unreachable via the public API: the loop body unconditionally sets `initial_total = page.total_count` on the first iteration, and every exit path from the loop either goes through `break` (after ≥1 page) or raises a different StarHistoryError. Only a refactoring bug (e.g. a future `continue` before the assignment, or an exception-swallowing wrapper) can leave `initial_total` None at line 607.","commonSituations":"Essentially never seen in production; appears only when someone edits the loop structure (moving the `initial_total` assignment behind a condition) or in mutant/coverage tests that exercise the dead branch.","solutions":["If you hit this after modifying the backfill loop, restore the invariant: the first `fetch_stargazer_page` result must set `initial_total` and `pages_required` before any `continue`/`break`.","Run the repository's test suite for scripts/star_history.py — this assertion exists to make loop refactorings fail loudly.","If untouched code raises it, report a control-flow bug; include the traceback showing how the loop exited without an exception."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    state = run_backfill(gateway, clock)\nexcept StarHistoryError as exc:\n    if \"returned no pages\" in str(exc):\n        raise RuntimeError(\"control-flow bug in backfill loop; report upstream\") from exc\n    raise","preventionTips":["Do not refactor the backfill loop without running its full test suite — this assertion exists to catch structural regressions.","Keep the initial_total assignment unconditional on the first page fetch if you must restructure the loop.","Never wrap fetch_stargazer_page in an exception swallower that could let the loop `continue` past the assignment."],"tags":["backfill","internal-invariant","unreachable-guard","defensive"],"backgroundTag":null,"analyzedSha":"b5b53acc57189a4a42e44a23e149dc655c98fe82","analyzedAt":"2026-08-14T22:29:33.146Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}