multica-ai/multica · error
extract binary: %w
Error message
extract binary: %w
What it means
After verification, the archive is unpacked via extractBinaryFromZip (Windows) or extractBinaryFromTarGz (others) looking for the 'multica'/'multica.exe' entry; any failure is wrapped as 'extract binary: %w'. Because the SHA-256 already matched the manifest, extraction errors almost always mean the archive layout changed rather than corruption.
Source
Thrown at server/internal/cli/update.go:442
// corrupted asset is rare enough that retrying through the same
// CDN is the right default; persistent failures will surface in
// the daemon log.
return "", fmt.Errorf("verify download: %w", err)
}
// Extract the binary from the archive.
binaryName := "multica"
if runtime.GOOS == "windows" {
binaryName = "multica.exe"
}
var binaryData []byte
if runtime.GOOS == "windows" {
binaryData, err = extractBinaryFromZip(bytes.NewReader(archiveData), binaryName)
} else {
binaryData, err = extractBinaryFromTarGz(bytes.NewReader(archiveData), binaryName)
}
if err != nil {
return "", fmt.Errorf("extract binary: %w", err)
}
// Atomic replace: write to temp file, then rename over the original.
dir := filepath.Dir(exePath)
tmpFile, err := os.CreateTemp(dir, "multica-update-*")
if err != nil {
return "", fmt.Errorf("create temp file: %w", err)
}
tmpPath := tmpFile.Name()
if _, err := tmpFile.Write(binaryData); err != nil {
tmpFile.Close()
os.Remove(tmpPath)
return "", fmt.Errorf("write temp file: %w", err)
}
tmpFile.Close()
// Preserve original file permissions.View on GitHub (pinned to 2c0912b6ec)
Solutions
- Download the asset and list its contents (tar -tzf / unzip -l) to see the actual binary name and layout.
- Align the expected binaryName ("multica"/"multica.exe") and archive extension with the release configuration in .goreleaser.yml.
- Check the wrapped message to distinguish 'binary not found' (layout) from 'gzip reader'/'read tar' (format).
- Re-release with the expected layout or fix the extractor to match the new one.
Example fix
null
Defensive patterns
Strategy: validation
Try / catch
out, err := cli.UpdateViaDownload(ver)
if err != nil {
msg := err.Error()
switch {
case strings.HasPrefix(msg, "extract binary: binary "):
// layout change: inspect archive listing, fix name_template
case strings.HasPrefix(msg, "extract binary: gzip reader"):
// format mismatch: asset is not gzip despite .tar.gz name
}
} Prevention
- Pin the inner binary name to 'multica' in release config
- Test one full self-update per platform per release in CI
- Keep releaseArchiveExtension in sync with actual packaging
When it happens
Trigger: The binary inside the archive was renamed or nested in a way that no longer matches filepath.Base(hdr.Name) == "multica"; the archive format for a platform switched (zip vs tar.gz) without updating releaseArchiveExtension; the checksum passed but the archive is a format Go's archive/* readers reject.
Common situations: GoReleaser name_template changes that renamed the inner binary; a release built by a fork with a different layout; new platform targets whose packaging differs.
Related errors
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/33917f3dc391008a.
Report an issue: GitHub.