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

  1. Re-run checkForUpdates to refresh browser_download_url, then download immediately
  2. If 403/429, respect the rate limit (see the API error) — wait or authenticate
  3. Allow objects.githubusercontent.com through proxies/firewalls
  4. 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

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


AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16). Data as JSON: /api/errors/1a090c1134519a3a. Report an issue: GitHub.