666ghj/MiroFish · error · FetchError

GitHub API network request failed

Error message

GitHub API network request failed

What it means

Raised when client.open(request, timeout=20) fails with URLError, TimeoutError, or OSError while establishing/sending the request. This bucket covers every transport-level failure before any HTTP response exists: DNS failure, connection refused, TLS errors, and the 20-second connect/read timeout expiring.

Source

Thrown at scripts/fetch_star_count.py:94

    request = urllib.request.Request(
        API_URL,
        headers={
            "Accept": "application/vnd.github+json",
            "Authorization": f"Bearer {token}",
            "User-Agent": "Repository-Star-History-Fetcher",
            "X-GitHub-Api-Version": API_VERSION,
        },
        method="GET",
    )
    client = opener or _build_opener()
    try:
        response = client.open(request, timeout=TIMEOUT_SECONDS)
    except urllib.error.HTTPError as exc:
        status = exc.code
        exc.close()
        raise _status_error(status) from None
    except (urllib.error.URLError, TimeoutError, OSError):
        raise FetchError("GitHub API network request failed") from None
    except Exception:
        raise FetchError("GitHub API request could not be started") from None

    try:
        with response:
            if response.geturl() != API_URL:
                raise FetchError("GitHub API redirect was refused")
            status = response.getcode()
            if status != 200:
                raise _status_error(status)
            payload = _read_response(response)
    except FetchError:
        raise
    except (TimeoutError, OSError):
        raise FetchError("GitHub API response could not be read") from None
    except Exception:
        raise FetchError("GitHub API response could not be processed") from None

View on GitHub (pinned to b5b53acc57)

Solutions

  1. Test reachability from the same host: curl -v --max-time 20 https://api.github.com/ (expect 200 or a rate-limit body).
  2. If a proxy is required, ensure HTTPS_PROXY is set and reachable; note the script builds its own opener, so proxy env handling comes from urllib's defaults.
  3. Retry after a short backoff — transient DNS/TLS failures are the most common cause and self-heal.
  4. For frequent CI flakes, schedule the workflow with retry logic (workflow_run re-run, or a wrapper that retries on this specific message).

Example fix

# before
try:
    count = fetch_star_count(os.environ["GITHUB_TOKEN"])
except FetchError as exc:
    sys.exit(f"error: {exc}")

# after: bounded retry for transport-level failures only
for attempt in range(3):
    try:
        count = fetch_star_count(os.environ["GITHUB_TOKEN"])
        break
    except FetchError as exc:
        if exc.args[0] != "GitHub API network request failed" or attempt == 2:
            raise
        time.sleep(2 ** attempt)
Defensive patterns

Strategy: retry

Validate before calling

import socket

# cheap pre-flight: DNS + TCP reachability before the real call
try:
    socket.create_connection(("api.github.com", 443), timeout=5).close()
except OSError as exc:
    raise SystemExit(f"no egress to api.github.com: {exc}") from None

Try / catch

last: Exception | None = None
for attempt in range(3):
    try:
        count = fetch_star_count(token)
        break
    except FetchError as exc:
        if exc.args[0] != "GitHub API network request failed":
            raise
        last, delay = exc, 2 ** attempt
        time.sleep(delay)
else:
    raise SystemExit(f"github unreachable after retries: {last}")

Prevention

When it happens

Trigger: No network egress (CI runner offline, firewall blocking api.github.com:443); DNS resolution failure; TLS handshake rejected by a filtering middlebox; request exceeding TIMEOUT_SECONDS=20 on a slow link.

Common situations: Self-hosted runners without internet; corporate firewalls requiring a proxy that urllib ignores (HTTPS_PROXY not honored by the custom opener); DNS outages; GitHub API connectivity blips.

Related errors


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