iOfficeAI/AionUi · error · Error
update.errors.githubApiTimeout
update.errors.githubApiTimeout
Error message
update.errors.githubApiTimeout
What it means
Thrown by fetchGitHubReleases when the AbortController timer (default 30s) fires before the GitHub API responds — the underlying fetch rejects with an AbortError, which is caught and re-thrown as this timeout error with the original error preserved as cause.
Source
Thrown at packages/desktop/src/process/bridge/updateBridge.ts:342
headers: {
Accept: 'application/vnd.github+json',
'User-Agent': DEFAULT_USER_AGENT,
},
signal: controller.signal,
});
if (!res.ok) {
throw new Error((await getI18n()).t('update.errors.githubApiFailed', { status: res.status }));
}
const json = (await res.json()) as unknown;
if (!Array.isArray(json)) {
throw new Error((await getI18n()).t('update.errors.githubApiNotArray'));
}
return json as GitHubReleaseApi[];
} catch (err: unknown) {
if (err instanceof Error && err.name === 'AbortError') {
throw new Error((await getI18n()).t('update.errors.githubApiTimeout'), { cause: err });
}
throw err;
} finally {
clearTimeout(timeoutId);
}
};
const CDN_MANIFEST_TIMEOUT_MS = 15000;
const GITHUB_NOTES_TIMEOUT_MS = 10000;
/**
* Fetch and parse the authoritative CDN channel manifest for the current
* platform/arch. Any failure here fails the manual check — the CDN is the
* single source of truth for "is there an update".
*/
const fetchCdnManifest = async (): Promise<CdnLatestManifest> => {
const url = `${CDN_BASE_URL}/${resolveCdnChannelFile()}`;
const controller = new AbortController();View on GitHub (pinned to 711aa0550e)
Solutions
- Retry — transient network slowness is the most common cause
- Verify api.github.com is reachable (curl -m 10 https://api.github.com) and not blocked by firewall/proxy
- If on a legitimately slow link, pass a larger timeoutMs to fetchGitHubReleases
- Check GitHub status page for degradation
- Fix VPN/DNS rules that blackhole the API host
Example fix
// before
const releases = await fetchGitHubReleases('aionui/aionui'); // 30s cap
// after
const releases = await fetchGitHubReleases('aionui/aionui', 90000); Defensive patterns
Strategy: retry
Validate before calling
// pre-flight reachability check (best effort)
await Promise.race([fetch('https://api.github.com', { method: 'HEAD' }), sleep(4000)]); Try / catch
try {
const releases = await fetchGitHubReleases(repo, timeoutMs);
} catch (err) {
if (err instanceof Error && err.message.includes('githubApiTimeout')) {
await backoff(2);
const releases = await fetchGitHubReleases(repo, timeoutMs * 2);
} else throw err;
} Prevention
- Pass a generous timeoutMs on slow links
- Pre-flight-check api.github.com reachability at app start
- Retry with exponential backoff — timeouts are usually transient
When it happens
Trigger: Calling fetchGitHubReleases when api.github.com takes longer than timeoutMs (default 30000) to respond: slow/high-latency links, GitHub degradation, large response over constrained bandwidth, or blocking middleware that hangs the socket.
Common situations: Firewalled environments where api.github.com is blackholed (connection opens but never responds); VPN routes with huge latency; GitHub partial outages; CI runners with restricted egress that silently stall instead of rejecting.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- update.errors.redirectNoLocation
- update.errors.tooManyRedirects
- update.errors.githubApiFailed
- update.errors.githubApiNotArray
- update.errors.cdnManifestTimeout
AI-assisted analysis of iOfficeAI/AionUi@711aa0550e (2026-08-28).
Data as JSON: /api/errors/e982752ece1347af.
Report an issue: GitHub.