{"record":{"id":"9d3b95ce8677223e","repo":"666ghj/MiroFish","slug":"github-graphql-request-timed-out","errorCode":null,"errorMessage":"GitHub GraphQL request timed out","messagePattern":"GitHub GraphQL request timed out","errorType":"exception","errorClass":"StarHistoryError","httpStatus":null,"severity":"error","filePath":"scripts/star_history.py","lineNumber":208,"sourceCode":"    def now(self) -> datetime:\n        return datetime.now(UTC).replace(microsecond=0)\n\n\nclass SubprocessCommandRunner:\n    def run(self, arguments: Sequence[str]) -> subprocess.CompletedProcess[str]:\n        try:\n            return subprocess.run(\n                list(arguments),\n                check=False,\n                capture_output=True,\n                text=True,\n                encoding=\"utf-8\",\n                timeout=45,\n            )\n        except FileNotFoundError as exc:\n            raise StarHistoryError(\"GitHub CLI (gh) is required for backfill\") from exc\n        except subprocess.TimeoutExpired as exc:\n            raise StarHistoryError(\"GitHub GraphQL request timed out\") from exc\n\n\nclass GhGraphQLGateway:\n    \"\"\"Production adapter for the one-time, maintainer-authorized backfill.\"\"\"\n\n    def __init__(self, runner: CommandRunner | None = None) -> None:\n        self._runner = runner or SubprocessCommandRunner()\n\n    def fetch_stargazer_page(self, after: str | None) -> StargazerPage:\n        arguments = [\n            \"gh\",\n            \"api\",\n            \"graphql\",\n            \"-f\",\n            f\"query={GRAPHQL_QUERY}\",\n            \"-f\",\n            f\"owner={REPOSITORY_OWNER}\",\n            \"-f\",","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/666ghj/MiroFish/blob/b5b53acc57189a4a42e44a23e149dc655c98fe82/scripts/star_history.py#L190-L226","documentation":"Raised when the `gh api graphql` subprocess exceeds its 45-second timeout (subprocess.TimeoutExpired). The GraphQL pagination request for 100 stargazers with starredAt normally completes in 1-3 s; hitting 45 s means gh is hung on network, auth re-prompting, or GitHub is slow.","triggerScenarios":"gh attempting interactive auth or waiting on a locked keychain because GH_TOKEN is absent; severely throttled network egress; a stargazer page request stalling against GitHub during an incident; gh waiting on an auth token refresh that needs a TTY.","commonSituations":"CI without GH_TOKEN/GITHUB_TOKEN where gh blocks on re-auth prompts; proxied networks adding latency; GitHub GraphQL API degradation; oversized PAGE_SIZE interacting with a slow GraphQL backend.","solutions":["Ensure non-interactive credentials: export GH_TOKEN (or GITHUB_TOKEN) before running backfill so gh never prompts.","Retry the backfill command — it pages through cursors, so a single stall aborts the run; re-running resumes from persisted state.","Check GitHub status and network latency to api.github.com; if consistently slow, raise the timeout in SubprocessCommandRunner.run from 45 s for this environment."],"exampleFix":"# before: gh may block waiting for interactive auth\nsubprocess.run([\"gh\", \"api\", \"graphql\", ...], timeout=45)\n\n# after: guarantee non-interactive auth\nenv = {**os.environ, \"GH_TOKEN\": os.environ[\"GH_TOKEN\"]}  # asserted present\nsubprocess.run([\"gh\", \"api\", \"graphql\", ...], timeout=45, env=env)","handlingStrategy":"retry","validationCode":"import os, shutil\n\n# preflight: gh present and non-interactive credentials available\nassert shutil.which(\"gh\"), \"gh not on PATH\"\nassert os.environ.get(\"GH_TOKEN\") or os.environ.get(\"GITHUB_TOKEN\"), (\n    \"set GH_TOKEN so gh never blocks on interactive auth (45 s timeout)\"\n)","typeGuard":null,"tryCatchPattern":"for attempt in range(2):\n    try:\n        run_backfill()\n        break\n    except StarHistoryError as exc:\n        if \"timed out\" not in str(exc):\n            raise\n        time.sleep(10)\nelse:\n    raise SystemExit(\"gh graphql timed out twice; check network and GH_TOKEN\")","preventionTips":["Always export GH_TOKEN/GITHUB_TOKEN in CI so gh never waits on a TTY prompt.","Backfill is restartable — on timeout, re-run and let it resume from persisted state.","Check `gh api rate_limit` before long backfills to avoid stalling against exhausted quotas."],"tags":["timeout","subprocess","github-cli","star-history","ci"],"backgroundTag":null,"analyzedSha":"b5b53acc57189a4a42e44a23e149dc655c98fe82","analyzedAt":"2026-08-14T22:29:33.146Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}