multica-ai/multica · error
binary %q not found in archive
Error message
binary %q not found in archive
What it means
extractBinaryFromTarGz iterated to io.EOF without finding a regular entry whose filepath.Base(name) equals the requested binary name; it returns 'binary %q not found in archive'. The archive itself was valid (checksum-verified) — its contents just do not contain 'multica' as a regular file at any directory depth.
Source
Thrown at server/internal/cli/update.go:494
}
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)
}
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.View on GitHub (pinned to 2c0912b6ec)
Solutions
- List the archive: `tar -tzf multica_*.tar.gz` and see what the binary is actually named.
- Re-release with the binary named 'multica' at the archive root (or nested in any directory — Base matching handles depth, not renaming).
- Update the expected binaryName in UpdateViaDownloadWithTimeout to match the shipped name.
- Verify the correct GOOS/GOARCH asset was selected by findReleaseAsset for the running machine.
Example fix
null
Defensive patterns
Strategy: validation
Type guard
func isBinaryNotFound(err error) bool {
return err != nil && strings.HasPrefix(err.Error(), "binary ") && strings.Contains(err.Error(), "not found in archive")
} Try / catch
data, err := extractBinaryFromTarGz(r, "multica")
if err != nil && isBinaryNotFound(err) {
// checksum passed but layout changed: list archive, fix name_template, re-release
} Prevention
- Keep the inner binary named 'multica' (or 'multica.exe') in release archives
- Verify archive contents in release CI with tar -tzf / unzip -l
- Note that matching uses filepath.Base, so subdirectories are fine but renames are not
When it happens
Trigger: The inner binary was renamed in the release config (e.g. to multica-server or a versioned name); the archive contains only a top-level directory with a different binary name; a non-Windows release accidentally packaged with the Windows name (multica.exe) so the Unix lookup misses.
Common situations: GoReleaser builds.name_template changed after shipping the updater; forks renaming the binary; releases that bundle multiple binaries where the expected one is absent for a platform.
Related errors
- extract binary: %w
- gzip reader: %w
- 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/39937f353ae16b13.
Report an issue: GitHub.