plandex-ai/plandex · error
failed to save the downloaded archive: %w
Error message
failed to save the downloaded archive: %w
What it means
doUpgrade streams the HTTP response body into the temp file with io.Copy. If the write fails mid-transfer (disk full, I/O error) or reading the response body fails (connection reset mid-download), it returns 'failed to save the downloaded archive: %w'. Note io.Copy also surfaces read errors from resp.Body, so truncated network transfers land here too.
Source
Thrown at app/cli/upgrade.go:120
downloadURL := fmt.Sprintf("https://github.com/plandex-ai/plandex/releases/download/%s/plandex_%s_%s_%s.tar.gz", escapedTag, version, runtime.GOOS, runtime.GOARCH)
resp, err := http.Get(downloadURL)
if err != nil {
return fmt.Errorf("failed to download the update: %w", err)
}
defer resp.Body.Close()
// Create a temporary file to save the downloaded archive
tempFile, err := os.CreateTemp("", "*.tar.gz")
if err != nil {
return fmt.Errorf("failed to create temporary file: %w", err)
}
defer os.Remove(tempFile.Name()) // Clean up file afterwards
// Copy the response body to the temporary file
_, err = io.Copy(tempFile, resp.Body)
if err != nil {
return fmt.Errorf("failed to save the downloaded archive: %w", err)
}
_, err = tempFile.Seek(0, 0)
if err != nil {
return fmt.Errorf("failed to seek in temporary file: %w", err)
}
// Now, extract the binary from the tempFile
gzr, err := gzip.NewReader(tempFile)
if err != nil {
return fmt.Errorf("failed to create gzip reader: %w", err)
}
defer gzr.Close()
tarReader := tar.NewReader(gzr)
for {
header, err := tarReader.Next()
if err == io.EOF {View on GitHub (pinned to e2d772072e)
Solutions
- Free disk space on the temp filesystem.
- Retry the upgrade on a stable connection.
- Check TMPDIR for a faster/larger filesystem and set TMPDIR accordingly.
- Download the release manually and install it if the network keeps dropping.
Example fix
// before (no size/status checks before copy)
_, err = io.Copy(tempFile, resp.Body)
// after (validate status and use a size-aware copy)
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("unexpected download status: %s", resp.Status)
}
if _, err = io.Copy(tempFile, resp.Body); err != nil {
return fmt.Errorf("failed to save the downloaded archive: %w", err)
} Defensive patterns
Strategy: validation
Validate before calling
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("download failed: %s", resp.Status)
}
// pre-check free space when Content-Length is known
if resp.ContentLength > 0 {
if st, err := os.Stat(os.TempDir()); err == nil {
_ = st // additionally use syscall.Statfs for free space in production
}
} Try / catch
n, err := io.Copy(tempFile, resp.Body)
if err != nil {
if resp.ContentLength > 0 && n < resp.ContentLength {
return fmt.Errorf("truncated download (%d/%d bytes): %w", n, resp.ContentLength, err)
}
return fmt.Errorf("failed to save the downloaded archive: %w", err)
} Prevention
- Ensure adequate free disk space before large downloads
- Download on a stable connection; retry on truncation
- Check HTTP status before writing the body
- Watch for proxies that cut long-running transfers
When it happens
Trigger: io.Copy(tempFile, resp.Body) errors: out of disk space while writing the archive, interrupted network connection during the download, or storage device I/O error.
Common situations: Full /tmp partition on a large release download; flaky Wi-Fi dropping mid-download; proxy terminating long transfers; disk quota exceeded.
Related errors
- error writing plan apply file: %v
- failed to read file %s: %v
- failed to open file %s: %w
- error getting update request: %v
- error creating account credentials directory: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/2054e65909987b10.
Report an issue: GitHub.