aaif-goose/goose · error
Download failed: ${response.status} ${response.statusText}
Error message
Download failed: ${response.status} ${response.statusText} What it means
The actual binary fetch of the update asset (browser_download_url from the release) returned a non-OK status. Distinct from the API-call error: here the release metadata was fine but the download endpoint failed — commonly 404 (asset deleted/re-upload raced), 403 (rate limit or expired signed redirect), or network-layer 5xx on the CDN.
Source
Thrown at ui/desktop/src/utils/githubUpdater.ts:181
latestVersion: string,
onProgress?: (percent: number) => void
): Promise<{ success: boolean; downloadPath?: string; extractedPath?: string; error?: string }> {
const downloadStartTime = Date.now();
try {
log.info('=== GitHubUpdater: STARTING DOWNLOAD ===');
log.info(`GitHubUpdater: Download URL: ${downloadUrl}`);
log.info(`GitHubUpdater: Version: ${latestVersion}`);
log.info(`GitHubUpdater: Timestamp: ${new Date().toISOString()}`);
log.info('GitHubUpdater: Initiating download fetch request...');
const response = await fetch(downloadUrl);
const fetchDuration = Date.now() - downloadStartTime;
log.info(
`GitHubUpdater: Download response received in ${fetchDuration}ms - Status: ${response.status} ${response.statusText}`
);
if (!response.ok) {
throw new Error(`Download failed: ${response.status} ${response.statusText}`);
}
// Get total size from headers
const contentLength = response.headers.get('content-length');
const totalSize = contentLength ? parseInt(contentLength, 10) : 0;
log.info(
`GitHubUpdater: Content-Length: ${totalSize} bytes (${(totalSize / 1024 / 1024).toFixed(2)} MB)`
);
if (!response.body) {
throw new Error('Response body is null');
}
let lastReportedPercent = -1; // Track last reported percentage to throttle updates
let lastLoggedPercent = -1; // Track for logging at 10% intervals
// Read the response stream
log.info('GitHubUpdater: Starting to read response stream...');
const reader = response.body.getReader();View on GitHub (pinned to 3810898a74)
Solutions
- Re-run checkForUpdates to refresh browser_download_url, then download immediately
- If 403/429, respect the rate limit (see the API error) — wait or authenticate
- Allow objects.githubusercontent.com through proxies/firewalls
- Retry with backoff for transient 5xx; the updater does not retry on its own
Defensive patterns
Strategy: retry
Try / catch
for (let i = 0; i < 3; i++) {
const response = await fetch(downloadUrl);
if (response.ok) break;
if (response.status === 403 || response.status === 429) throw new Error('rate limited');
await new Promise(r => setTimeout(r, 2 ** i * 500));
if (i === 2) throw new Error(`Download failed: ${response.status}`);
} Prevention
- Re-check-for-updates right before downloading so browser_download_url is fresh
- Retry transient 5xx with backoff; treat 404 as stale metadata, not transient
- Verify CDN domains are reachable from managed networks
When it happens
Trigger: downloadUpdate() in the GitHub fallback path; asset was replaced right after the metadata check so the old URL 404s; unauthenticated rate limit hit during download; proxies blocking objects.githubusercontent.com.
Common situations: Flaky connections mid-release-publish; corporate proxies/firewalls blocking the GitHub CDN domain; retried downloads after long pauses where the signed URL expired.
Related errors
- GitHub API returned ${response.status}: ${response.statusTex
- Response body is null
- HTTP error! status: ${response.status}
- Download failed after {} retries: {}
- Failed to download: HTTP {}
AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16).
Data as JSON: /api/errors/1a090c1134519a3a.
Report an issue: GitHub.