github/copilot-sdk · error
failed to save tarball
Error message
failed to save tarball: %w
What it means
downloadCLIBinary streams the release tarball from the network into a local file while simultaneously computing its SHA-256 via io.MultiWriter. This error wraps any failure from that io.Copy of resp.Body, meaning the download was interrupted or the write to the tarball file failed mid-stream. It is thrown to distinguish save-time I/O problems from earlier file-creation problems.
Solutions
- Retry the download; the error is usually transient (network or disk pressure).
- Check free disk space on the destination filesystem (tarballs plus extracted binaries can be hundreds of MB).
- Verify network/proxy stability (HTTP_PROXY, VPN, firewall) and re-run buildBundle.
- Check upstream release-host availability if failures persist across retries.
Example fix
// before: single-shot download with no retry
tarballPath, licensePath, err := downloadCLIBinary(...)
// after: retry transient save failures
var tarballPath, licensePath string
for attempt := 0; attempt < 3; attempt++ {
tarballPath, licensePath, err = downloadCLIBinary(...)
if err == nil || !strings.Contains(err.Error(), "failed to save tarball") {
break
}
time.Sleep(time.Duration(attempt+1) * 2 * time.Second)
} Defensive patterns
Strategy: retry
Validate before calling
// preflight disk space before downloading
if st, err := os.Statfs(destDir); err == nil && st.Avail < 1<<30 {
return fmt.Errorf("insufficient space in %s for tarball download", destDir)
} Try / catch
for i := 0; i < 3; i++ {
path, lic, err := downloadCLIBinary(...)
if err == nil { break }
if isIOCopyFailure(err) { time.Sleep(backoff(i)); continue }
return err
} Prevention
- Ensure ample free disk space on the destination filesystem before bundling.
- Use a stable network connection or resumable download for large assets.
- Wrap the download in bounded retries with backoff.
- Monitor proxy/VPN stability in CI environments.
When it happens
Trigger: io.Copy(io.MultiWriter(tarballFile, hasher), resp.Body) returns a non-nil error while downloading the release tarball — network drop, connection reset, disk full while writing the file, or the HTTP body read failing.
Common situations: Flaky network or proxy dropping long downloads of large CLI binaries; disk quota/full /tmp; corporate firewall terminating TLS mid-transfer; transient GitHub release-asset download failure.
Related errors
- failed to download checksums
- failed to read checksums
- failed to download
- failed to close tarball file
- Failed to write a frame to the in-process runtime…
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/f91c280ec4e26f91.
Report an issue: GitHub.
Appendix: source
Thrown at go/cmd/bundler/main.go:1022
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)
}
if err := tarballFile.Close(); err != nil {
return "", "", fmt.Errorf("failed to close tarball file: %w", err)
}
actualChecksum := fmt.Sprintf("%x", hasher.Sum(nil))
if actualChecksum != expectedChecksum {
return "", "", fmt.Errorf(
"checksum mismatch for %s: expected %s, got %s",
assetName,
expectedChecksum,
actualChecksum,
)
}
// The SDK release package intentionally omits the legacy SEA binary. Preserve
// embeddedcli.Path compatibility by installing the runtime wrapper under the
// historical copilot[.exe] name; the normal client path uses the adjacent
// wrapper/runtime.node pair directly.View on GitHub (pinned to cd8cf15dc3)