666ghj/MiroFish · error · StarHistoryError

GitHub CLI (gh) is required for backfill

Error message

GitHub CLI (gh) is required for backfill

What it means

Raised by SubprocessCommandRunner.run when subprocess.run raises FileNotFoundError while launching the gh command — the GitHub CLI executable is not installed or not on PATH for the process running scripts/star_history.py. The backfill path shells out to `gh api graphql`, so gh is a hard runtime dependency for the one-time backfill command.

Source

Thrown at scripts/star_history.py:206

class SystemClock:
    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",

View on GitHub (pinned to b5b53acc57)

Solutions

  1. Install GitHub CLI: brew install gh (macOS), apt install gh / conda install gh (Linux), winget install GitHub.cli (Windows), then verify `gh --version`.
  2. If gh is installed but not found, fix PATH for the executing context (export PATH="$PATH:/usr/local/bin" or add it to the unit/cron environment).
  3. Authenticate once before backfill: gh auth login (or set GH_TOKEN), since gh api needs credentials.
  4. Remember only the backfill subcommand needs gh — scheduled updates use the credential-free fetch_star_count helper.

Example fix

# before: CI job assumes gh exists
- run: python scripts/star_history.py backfill

# after: install and auth explicitly
- run: |
    python scripts/star_history.py backfill
  env:
    GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# plus a setup step: sudo apt-get install -y gh  (or use ghcli/setup-gh action)
Defensive patterns

Strategy: validation

Validate before calling

import shutil

if shutil.which("gh") is None:
    raise SystemExit(
        "GitHub CLI not found. Install it (brew/apt install gh) and "
        "ensure it is on PATH before running backfill."
    )
subprocess.run(["python", "scripts/star_history.py", "backfill"], check=True)

Try / catch

try:
    run_backfill()
except StarHistoryError as exc:
    if "GitHub CLI (gh) is required" in str(exc):
        raise SystemExit("install gh and re-run: brew install gh && gh auth login")
    raise

Prevention

When it happens

Trigger: Running `star_history.py backfill` on a machine/container without the gh binary; PATH not including gh in CI, cron, or a service context; gh installed via homebrew but the script runs under a different user/environment.

Common situations: Fresh CI image without gh; local dev on a machine that only has hub or git; systemd/cron jobs with minimal PATH; gh installed for the interactive user but the script runs as root.

Related errors


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