plandex-ai/plandex · error
failed to create gzip reader: %w
Error message
failed to create gzip reader: %w
What it means
doUpgrade wraps the downloaded archive in a gzip.NewReader to decompress the tar.gz release. If the stream's first bytes are not valid gzip data, it returns 'failed to create gzip reader: %w'. This almost always means the downloaded file is not the expected release tarball.
Source
Thrown at app/cli/upgrade.go:131
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 {
break // End of archive
}
if err != nil {
return fmt.Errorf("failed to read tar header: %w", err)
}
// Check if the current file is the binary
if header.Typeflag == tar.TypeReg && (header.Name == "plandex" || header.Name == "plandex.exe") {
err = update.Apply(tarReader, update.Options{})
if err != nil {
if errors.Is(err, fs.ErrPermission) {View on GitHub (pinned to e2d772072e)
Solutions
- Check resp.StatusCode == 200 before saving the body (404/HTML pages cause this).
- Verify the release tag cli/v<version> and asset plandex_<version>_<GOOS>_<GOARCH>.tar.gz exist on GitHub.
- Clear/adjust proxy settings that may intercept the download.
- Retry the download to rule out truncation.
Example fix
// before (no status check; error page saved as tar.gz)
resp, err := http.Get(downloadURL)
if err != nil {
return fmt.Errorf("failed to download the update: %w", err)
}
defer resp.Body.Close()
// after
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("unexpected download status: %s", resp.Status)
} Defensive patterns
Strategy: validation
Validate before calling
// before decompressing, check HTTP status and magic bytes
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("unexpected status: %s", resp.Status)
}
head := make([]byte, 2)
if _, err := io.ReadFull(tempFile, head); err != nil {
return fmt.Errorf("archive too short: %w", err)
}
if head[0] != 0x1f || head[1] != 0x8b {
return fmt.Errorf("not a gzip file")
}
tempFile.Seek(0, io.SeekStart) Try / catch
gzr, err := gzip.NewReader(tempFile)
if err != nil {
return fmt.Errorf("failed to create gzip reader: %w — downloaded file may not be a valid release archive", err)
} Prevention
- Always verify HTTP 200 before saving the body
- Validate the gzip magic bytes (1f 8b) before parsing
- Confirm the release asset name matches GOOS/GOARCH
- Beware proxies injecting HTML into downloads
When it happens
Trigger: gzip.NewReader(tempFile) fails because the downloaded content is not gzip — a 404/HTML error page was saved instead of the archive, the download was truncated, or a proxy returned an intercepted response.
Common situations: Release tag typo/version not published so GitHub returns a 404 page; corporate proxy injecting an HTML block page; partial download from a dropped connection; wrong GOOS/GOARCH asset name.
Related errors
- failed to read tar header: %w
- connection to plan stream timed out due to missing heartbeat
- error loading accounts: %v
- error signing in to new account: %v
- error selecting account: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/cdead845249efb71.
Report an issue: GitHub.