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

  1. Download the asset and list its contents (tar -tzf / unzip -l) to see the actual binary name and layout.
  2. Align the expected binaryName ("multica"/"multica.exe") and archive extension with the release configuration in .goreleaser.yml.
  3. Check the wrapped message to distinguish 'binary not found' (layout) from 'gzip reader'/'read tar' (format).
  4. 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

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.