github/copilot-sdk · error

failed to download

Error message

failed to download: %w

What it means

Returned by downloadCLIBinary when fetching the verified CLI release tarball fails (network error, bad download URL, HTTP failure, or interrupted transfer) after the release checksum was resolved. The wrapped cause identifies the underlying download error; callers such as buildBundle treat it as a fatal bundle failure.

Solutions

  1. Verify network/proxy connectivity (curl -I the tarball URL)
  2. Confirm cliVersion and baseURL are correct so the URL is valid
  3. Add retry-with-backoff around the download for transient errors
  4. Check HTTPS_PROXY/HTTP_PROXY env and corporate CA certs for TLS failures

Example fix

// before
resp, err := releaseHTTPClient.Get(tarballURL)
if err != nil {
	return "", "", fmt.Errorf("failed to download: %w", err)
}
// after
var resp *http.Response
for attempt := 0; attempt < 3; attempt++ {
	resp, err = releaseHTTPClient.Get(tarballURL)
	if err == nil {
		break
	}
	time.Sleep(time.Duration(attempt+1) * time.Second)
}
if err != nil {
	return "", "", fmt.Errorf("failed to download after retries: %w", err)
}
Defensive patterns

Strategy: retry

Validate before calling

u, err := url.Parse(releaseDownloadURL(cliVersion, assetName))
if err != nil {
	return fmt.Errorf("invalid release URL: %w", err)
}
resp, err := http.Head(u.String())
if err != nil || resp.StatusCode != http.StatusOK {
	return fmt.Errorf("release asset unreachable: %s", u)
}

Try / catch

resp, err := releaseHTTPClient.Get(tarballURL)
if err != nil {
	var netErr net.Error
	if errors.As(err, &netErr) && netErr.Timeout() {
		// exponential backoff retry
	}
	return "", "", fmt.Errorf("failed to download: %w", err)
}

Prevention

When it happens

Trigger: releaseHTTPClient.Get(tarballURL) fails with a transport error: DNS failure, connection refused/reset, TLS handshake error, timeout, or offline environment.

Common situations: Build machine without internet or behind a blocking proxy; wrong release host in baseURL; VPN/firewall dropping large downloads; transient upstream outage.

Related errors


AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09). Data as JSON: /api/errors/4c9a54a74971122f. Report an issue: GitHub.

Appendix: source

Thrown at go/cmd/bundler/main.go:1004

	return checksum, nil
}

// downloadCLIBinary downloads the verified release package and extracts the CLI binary. It
// returns the extracted binary path and the downloaded tarball path (retained so
// callers can extract additional files, such as the runtime library).
func downloadCLIBinary(runtimePlatform, binaryName, cliVersion, destDir string) (string, string, error) {
	assetName := releaseAssetName(cliVersion, runtimePlatform)
	expectedChecksum, err := getReleaseChecksum(cliVersion, assetName)
	if err != nil {
		return "", "", err
	}
	tarballURL := releaseDownloadURL(cliVersion, assetName)

	fmt.Printf("Downloading from %s...\n", tarballURL)

	resp, err := releaseHTTPClient.Get(tarballURL)
	if err != nil {
		return "", "", fmt.Errorf("failed to download: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return "", "", fmt.Errorf("failed to download: %s", resp.Status)
	}

	// Save tarball to temp file
	tarballPath := filepath.Join(destDir, assetName)
	tarballFile, err := os.Create(tarballPath)
	if err != nil {
		return "", "", fmt.Errorf("failed to create tarball file: %w", err)
	}

	hasher := sha256.New()
	if _, err := io.Copy(io.MultiWriter(tarballFile, hasher), resp.Body); err != nil {
		tarballFile.Close()
		return "", "", fmt.Errorf("failed to save tarball: %w", err)

View on GitHub (pinned to cd8cf15dc3)