multica-ai/multica · error
gzip reader: %w
Error message
gzip reader: %w
What it means
extractBinaryFromTarGz wraps the archive in gzip.NewReader first; failure returns 'gzip reader: %w' (flate.CorruptInputError or ErrHeader). Note the SHA-256 was verified against the manifest before extraction, so reaching this error with a valid checksum usually means the asset is not actually gzip data despite its name — a packaging bug rather than a corrupted transfer.
Source
Thrown at server/internal/cli/update.go:486
return "", fmt.Errorf("chmod temp file: %w", err)
}
// Replace the original binary. On Windows this moves the running executable
// aside first; on Unix a plain rename over the running inode is fine.
if err := replaceBinary(tmpPath, exePath); err != nil {
os.Remove(tmpPath)
return "", fmt.Errorf("replace binary: %w", err)
}
return fmt.Sprintf("Downloaded %s and replaced %s", assetName, exePath), nil
}
// extractBinaryFromTarGz reads a .tar.gz stream and returns the contents of the
// named file entry.
func extractBinaryFromTarGz(r io.Reader, name string) ([]byte, error) {
gz, err := gzip.NewReader(r)
if err != nil {
return nil, fmt.Errorf("gzip reader: %w", err)
}
defer gz.Close()
tr := tar.NewReader(gz)
for {
hdr, err := tr.Next()
if err == io.EOF {
return nil, fmt.Errorf("binary %q not found in archive", name)
}
if err != nil {
return nil, fmt.Errorf("read tar: %w", err)
}
// Match the binary name (may be prefixed with a directory).
if filepath.Base(hdr.Name) == name && hdr.Typeflag == tar.TypeReg {
data, err := io.ReadAll(tr)
if err != nil {
return nil, fmt.Errorf("read binary: %w", err)
}View on GitHub (pinned to 2c0912b6ec)
Solutions
- Inspect the asset: `file multica_*.tar.gz` — it reports the real format.
- Fix the release pipeline so the compression matches the file extension expected by the updater.
- Re-release with consistent packaging, then retry the update.
- If a custom format is intentional, extend the extractor to handle it and update asset naming.
Example fix
null
Defensive patterns
Strategy: validation
Validate before calling
// sniff magic bytes before extraction
head := make([]byte, 2)
if _, err := io.ReadFull(bytes.NewReader(archiveData), head); err == nil {
if !(head[0] == 0x1f && head[1] == 0x8b) {
// not gzip despite .tar.gz name: reject before gzip.NewReader
}
} Type guard
func isGzip(data []byte) bool {
return len(data) >= 2 && data[0] == 0x1f && data[1] == 0x8b
} Try / catch
data, err := extractBinaryFromTarGz(r, "multica")
if err != nil && strings.HasPrefix(err.Error(), "gzip reader") {
// packaging mismatch: asset is not gzip; check `file` on the downloaded artifact
} Prevention
- Keep release compression config and file extensions consistent
- Validate asset format with `file` in release CI before publishing
- Don't rename artifacts to .tar.gz if they aren't gzip-compressed
When it happens
Trigger: A non-Windows asset uploaded as plain tar, zip, or compressed with another algorithm (zstd) while named .tar.gz; a release pipeline change in the compression config; a checksum manifest computed over the wrong file so a different-format archive passes verification.
Common situations: GoReleaser config edits (e.g. switching to zstd or disabling compression) without updating the extension logic in releaseArchiveExtension; manually re-packaged release assets that kept the old filename.
Related errors
- extract binary: %w
- binary %q not found in archive
- read tar: %w
- [package] --all-platforms cannot be combined with explicit p
- [package] --all-platforms is only supported on macOS hosts (
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/4a2ad39adab55b0d.
Report an issue: GitHub.