multica-ai/multica · error
read zip data: %w
Error message
read zip data: %w
What it means
extractBinaryFromZip first buffers the entire stream with io.ReadAll; failure returns 'read zip data: %w'. The reader comes from a bytes.NewReader over already-verified bytes in the update path, so in production this error is rare and usually surfaces when the function is reused with a different io.Reader (network, file) that fails mid-read.
Source
Thrown at server/internal/cli/update.go:516
}
// 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)
}
return data, nil
}
}
}
// extractBinaryFromZip reads a .zip stream and returns the contents of the
// named file entry. The zip format requires random access, so the full archive
// is buffered in memory.
func extractBinaryFromZip(r io.Reader, name string) ([]byte, error) {
buf, err := io.ReadAll(r)
if err != nil {
return nil, fmt.Errorf("read zip data: %w", err)
}
zr, err := zip.NewReader(bytes.NewReader(buf), int64(len(buf)))
if err != nil {
return nil, fmt.Errorf("zip reader: %w", err)
}
for _, f := range zr.File {
if filepath.Base(f.Name) == name && !f.FileInfo().IsDir() {
rc, err := f.Open()
if err != nil {
return nil, fmt.Errorf("open zip entry: %w", err)
}
defer rc.Close()
data, err := io.ReadAll(rc)
if err != nil {
return nil, fmt.Errorf("read binary: %w", err)View on GitHub (pinned to 2c0912b6ec)
Solutions
- Ensure the reader passed in stays open and unmodified for the full duration of the call.
- Pre-buffer the data yourself (io.ReadAll) and pass bytes.NewReader if the source is flaky or rate-limited.
- Retry the read with a fresh reader — mid-stream failures from sockets are transient.
- For OOM-adjacent failures, free memory or stream instead of buffering the whole archive.
Example fix
// before rc, _ := http.Get(url) data, err := extractBinaryFromZip(rc.Body, "multica.exe") // socket may reset mid-read // after rc, _ := http.Get(url) buf, _ := io.ReadAll(rc.Body) rc.Body.Close() data, err := extractBinaryFromZip(bytes.NewReader(buf), "multica.exe")
Defensive patterns
Strategy: validation
Validate before calling
// pre-buffer flaky sources before calling extractBinaryFromZip
buf, err := io.ReadAll(src)
if err != nil {
return err // handle source failure here, not inside extraction
}
data, err := extractBinaryFromZip(bytes.NewReader(buf), "multica.exe") Try / catch
data, err := extractBinaryFromZip(r, "multica.exe")
if err != nil && strings.HasPrefix(err.Error(), "read zip data") {
// source reader failed mid-buffer: retry with a fresh, fully-buffered reader
} Prevention
- Pass bytes.NewReader over fully-read data, not live network readers
- Keep the source reader open and untouched for the whole call
- In the updater path this error is rare because bytes are pre-buffered and verified
When it happens
Trigger: Calling extractBinaryFromZip directly with a network reader that times out or resets; a file handle closed concurrently; memory exhaustion during buffering of a very large stream (allocation failure surfaces as a read/panic path).
Common situations: Refactoring the updater to stream the zip instead of pre-buffering; tests feeding truncated readers; concurrent close of the underlying source.
Related errors
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/965cebf8141de397.
Report an issue: GitHub.