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
- Retry after the rate-limit window (check X-RateLimit-Reset on the 403/429 response).
- 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.
- Add a conditional/unauthenticated PAT via Authorization header to raise the rate limit if this is a frequently shared dashboard.
- 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
- Cache the last successful release check and only refetch on an explicit user action or long TTL.
- For regions that block api.github.com, proxy the lookup through the backend where egress is controllable.
- Treat update checks as best-effort: never block dashboard usage on their failure.
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.