iOfficeAI/AionUi · error · Error
update.errors.downloadFailed
update.errors.downloadFailed
Error message
update.errors.downloadFailed
What it means
Thrown when downloading an update artifact fails at the HTTP level: the response status is not ok (non-2xx). The status code is interpolated into the i18n message.
Source
Thrown at packages/desktop/src/process/bridge/updateBridge.ts:523
downloadId,
status,
receivedBytes,
totalBytes,
percent,
bytesPerSecond,
});
};
emitThrottled('starting');
log.info('[update-download] Downloading from URL:', url);
let stream: fs.WriteStream | null = null;
try {
const res = await fetchWithAllowlistedRedirects(url, abortController.signal);
if (!res.ok) {
throw new Error((await getI18n()).t('update.errors.downloadFailed', { status: res.status }));
}
const contentLengthHeader = res.headers.get('content-length');
if (contentLengthHeader) {
const parsed = parseInt(contentLengthHeader, 10);
if (Number.isFinite(parsed) && parsed > 0) {
totalBytes = parsed;
}
}
if (!res.body) {
throw new Error((await getI18n()).t('update.errors.downloadNoBody'));
}
stream = fs.createWriteStream(file_path);
const reader = res.body.getReader();
let doneReading = false;View on GitHub (pinned to 711aa0550e)
Solutions
- Retry the download — transient CDN 5xx or artifact propagation delay is common right after a release
- Verify the artifact URL from the manifest opens directly (curl -I) and check the status code
- Re-fetch the manifest to get a fresh URL in case the old one was rotated
- If 403, check CDN auth/signature configuration and whether the download host requires headers
Example fix
// before
const res = await fetchWithAllowlistedRedirects(url, abortController.signal);
if (!res.ok) {
throw new Error((await getI18n()).t('update.errors.downloadFailed', { status: res.status }));
}
// after (one retry for transient failures)
let res = await fetchWithAllowlistedRedirects(url, abortController.signal);
if ((res.status === 404 || res.status >= 500) && !retried) {
retried = true;
await new Promise((r) => setTimeout(r, 2000));
res = await fetchWithAllowlistedRedirects(url, abortController.signal);
}
if (!res.ok) {
throw new Error((await getI18n()).t('update.errors.downloadFailed', { status: res.status }));
} Defensive patterns
Strategy: retry
Validate before calling
const head = await fetch(artifactUrl, { method: 'HEAD' });
if (!head.ok) { /* don't start the download; surface status */ } Try / catch
catch (err) {
if (err instanceof Error && err.message.includes('downloadFailed')) {
await backoffRetry(); // one retry for 404/5xx after fresh manifest fetch
}
throw err;
} Prevention
- HEAD-check artifact URLs before starting large downloads
- Re-fetch the manifest right before downloading to get fresh URLs
- Alert on CDN 4xx rates for artifact paths
When it happens
Trigger: fetchWithAllowlistedRedirects returns 403/404/5xx for the artifact URL — e.g. the file was removed from the CDN, the URL expired (signed link), or the server errored.
Common situations: Artifact deleted/rotated on the CDN while the manifest still references it, expired pre-signed URLs, region-blocked downloads, or CDN misconfiguration. 404 after a new release rollout is typical.
Related errors
- update.errors.cdnManifestFailed
- update.errors.cdnManifestInvalid
- update.errors.cdnManifestTimeout
- update.errors.downloadNoBody
- update.errors.githubApiFailed
AI-assisted analysis of iOfficeAI/AionUi@711aa0550e (2026-08-28).
Data as JSON: /api/errors/61267ae16a48d420.
Report an issue: GitHub.