666ghj/MiroFish · error · StarHistoryError

GitHub GraphQL request timed out

Error message

GitHub GraphQL request timed out

What it means

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.

Source

Thrown at scripts/star_history.py:208

    def now(self) -> datetime:
        return datetime.now(UTC).replace(microsecond=0)


class SubprocessCommandRunner:
    def run(self, arguments: Sequence[str]) -> subprocess.CompletedProcess[str]:
        try:
            return subprocess.run(
                list(arguments),
                check=False,
                capture_output=True,
                text=True,
                encoding="utf-8",
                timeout=45,
            )
        except FileNotFoundError as exc:
            raise StarHistoryError("GitHub CLI (gh) is required for backfill") from exc
        except subprocess.TimeoutExpired as exc:
            raise StarHistoryError("GitHub GraphQL request timed out") from exc


class GhGraphQLGateway:
    """Production adapter for the one-time, maintainer-authorized backfill."""

    def __init__(self, runner: CommandRunner | None = None) -> None:
        self._runner = runner or SubprocessCommandRunner()

    def fetch_stargazer_page(self, after: str | None) -> StargazerPage:
        arguments = [
            "gh",
            "api",
            "graphql",
            "-f",
            f"query={GRAPHQL_QUERY}",
            "-f",
            f"owner={REPOSITORY_OWNER}",
            "-f",

View on GitHub (pinned to b5b53acc57)

Solutions

  1. Ensure non-interactive credentials: export GH_TOKEN (or GITHUB_TOKEN) before running backfill so gh never prompts.
  2. Retry the backfill command — it pages through cursors, so a single stall aborts the run; re-running resumes from persisted state.
  3. 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.

Example fix

# before: gh may block waiting for interactive auth
subprocess.run(["gh", "api", "graphql", ...], timeout=45)

# after: guarantee non-interactive auth
env = {**os.environ, "GH_TOKEN": os.environ["GH_TOKEN"]}  # asserted present
subprocess.run(["gh", "api", "graphql", ...], timeout=45, env=env)
Defensive patterns

Strategy: retry

Validate before calling

import os, shutil

# preflight: gh present and non-interactive credentials available
assert shutil.which("gh"), "gh not on PATH"
assert os.environ.get("GH_TOKEN") or os.environ.get("GITHUB_TOKEN"), (
    "set GH_TOKEN so gh never blocks on interactive auth (45 s timeout)"
)

Try / catch

for attempt in range(2):
    try:
        run_backfill()
        break
    except StarHistoryError as exc:
        if "timed out" not in str(exc):
            raise
        time.sleep(10)
else:
    raise SystemExit("gh graphql timed out twice; check network and GH_TOKEN")

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Related errors


AI-assisted analysis of 666ghj/MiroFish@b5b53acc57 (2026-08-14). Data as JSON: /api/errors/9d3b95ce8677223e. Report an issue: GitHub.