QuantumNous/new-api · info · Error

Failed to contact GitHub releases API

Error message

Failed to contact GitHub releases API

What it means

Thrown by the update checker when fetch of the GitHub releases API (api.github.com/repos/Calcium-Ion/new-api/releases/latest) returns a non-OK HTTP status. This is a direct browser-to-GitHub fetch, not a backend proxy call, so the dashboard's origin is the client.

Source

Thrown at web/src/features/system-settings/maintenance/update-checker-section.tsx:70

  const uptime = startTime ? formatTimestamp(startTime) : t('Unknown')
  const version = currentVersion || t('Unknown')

  const handleCheckUpdates = async () => {
    setChecking(true)
    try {
      const response = await fetch(
        'https://api.github.com/repos/Calcium-Ion/new-api/releases/latest',
        {
          headers: {
            Accept: 'application/vnd.github+json',
            'User-Agent': 'new-api-dashboard',
          },
        }
      )

      if (!response.ok) {
        throw new Error(t('Failed to contact GitHub releases API'))
      }

      const data = (await response.json()) as ReleaseInfo
      if (!data?.tag_name) {
        throw new Error(t('Unexpected release payload'))
      }

      if (currentVersion && data.tag_name === currentVersion) {
        toast.success(
          t('You are running the latest version ({{version}}).', {
            version: data.tag_name,
          })
        )
        return
      }

      setRelease(data)
      setDialogOpen(true)

View on GitHub (pinned to e2c7aa7b10)

Solutions

  1. Retry after the rate-limit window (check X-RateLimit-Reset on the 403/429 response).
  2. If api.github.com is blocked in the deployment region, proxy the check through the backend or a mirror domain instead of fetching from the browser.
  3. Add a conditional/unauthenticated PAT via Authorization header to raise the rate limit if this is a frequently shared dashboard.
  4. Confirm network egress and DNS from users' browsers; this fetch happens client-side, not server-side.

Example fix

// before
if (!response.ok) {
  throw new Error(t('Failed to contact GitHub releases API'))
}
// after: surface rate-limit info explicitly
if (!response.ok) {
  const reset = response.headers.get('X-RateLimit-Reset')
  throw new Error(
    response.status === 403 || response.status === 429
      ? t('GitHub API rate limited. Try again later.')
      : t('Failed to contact GitHub releases API')
  )
}
Defensive patterns

Strategy: retry

Try / catch

try {
  const response = await fetch(url, { headers: { Accept: 'application/vnd.github+json', 'User-Agent': 'new-api-dashboard' } })
  if (response.status === 403 || response.status === 429) {
    // rate limited — back off, do not spam retries
    throw new Error(t('GitHub API rate limited. Try again later.'))
  }
  if (!response.ok) throw new Error(t('Failed to contact GitHub releases API'))
  …
} catch { /* network/CORS failure — show offline state, keep current version UI */ }

Prevention

When it happens

Trigger: GitHub rate limiting (60 req/h per IP unauthenticated, common behind shared NAT/corporate proxies), HTTP 403/429 from rate limits, 5xx from GitHub, corporate firewall/proxy blocking api.github.com, or DNS/TLS failure.

Common situations: Many users behind one egress IP trip the unauthenticated rate limit; air-gapped or China-mainland deployments where api.github.com is slow or blocked; ad-blocker/privacy extension interfering; GitHub outage.

Related errors


AI-assisted analysis of QuantumNous/new-api@e2c7aa7b10 (2026-08-15). Data as JSON: /api/errors/5393f151cae0ec64. Report an issue: GitHub.