multica-ai/multica · error

empty expected checksum for %q

Error message

empty expected checksum for %q

What it means

verifyAssetSHA256 refuses to verify when the expected checksum string is empty — an assertion that the parse step produced a real digest. It is a fail-closed guard: an empty expected value would make a naive comparison trivially bypassable, so it errors naming the asset instead.

Source

Thrown at server/internal/cli/update.go:217

		if len(fields) < 2 {
			continue
		}
		if fields[1] == assetName {
			return strings.ToLower(fields[0]), nil
		}
	}
	if err := scanner.Err(); err != nil {
		return "", fmt.Errorf("read checksum manifest: %w", err)
	}
	return "", fmt.Errorf("checksum for %q not found in manifest", assetName)
}

// verifyAssetSHA256 returns nil when the SHA-256 of data matches the lowercase
// hex expected value, or an error otherwise. The error includes both digests
// so a corrupted asset is diagnosable from the log without re-downloading.
func verifyAssetSHA256(data []byte, expectedHex, assetName string) error {
	if expectedHex == "" {
		return fmt.Errorf("empty expected checksum for %q", assetName)
	}
	sum := sha256.Sum256(data)
	actual := hex.EncodeToString(sum[:])
	if !strings.EqualFold(actual, expectedHex) {
		return fmt.Errorf("checksum mismatch for %q: expected %s, got %s", assetName, expectedHex, actual)
	}
	return nil
}

func fetchReleaseByTag(tag string) (*GitHubRelease, error) {
	client := &http.Client{Timeout: 10 * time.Second}
	req, err := http.NewRequest(http.MethodGet, "https://api.github.com/repos/multica-ai/multica/releases/tags/"+tag, nil)
	if err != nil {
		return nil, err
	}
	req.Header.Set("Accept", "application/vnd.github+json")

	resp, err := client.Do(req)

View on GitHub (pinned to 2c0912b6ec)

Solutions

  1. Inspect checksums.txt for the affected asset's line and restore the full 64-char SHA-256 hex digest
  2. Regenerate the manifest with GoReleaser rather than editing it by hand
  3. Re-download the manifest to rule out truncation/corruption in transit

Example fix

# before
     multica-cli-1.2.3-linux-amd64.tar.gz

# after
3f2a...e1  multica-cli-1.2.3-linux-amd64.tar.gz
Defensive patterns

Strategy: validation

Validate before calling

if expectedHex == "" || len(expectedHex) != 64 {
	// manifest line is malformed; refetch or reject before verifying
	return fmt.Errorf("bad manifest entry")
}

Type guard

func isValidSHA256Hex(s string) bool {
	if len(s) != 64 { return false }
	for _, r := range s {
		if !strings.ContainsRune("0123456789abcdefABCDEF", r) { return false }
	}
	return true
}

Try / catch

if err := cli.VerifyAssetSHA256(data, expected, name); err != nil {
	if strings.Contains(err.Error(), "empty expected checksum") {
		// manifest is defective; refuse the update rather than comparing blindly
	}
}

Prevention

When it happens

Trigger: A checksums.txt line whose hash field is empty or whitespace (malformed line like ' filename' that still yields two fields after splitting), or a caller passing an unpopulated expected value. Not normally reachable via clean GoReleaser output.

Common situations: Hand-edited manifests with the hash accidentally deleted; whitespace-corrupted downloads; future refactors passing a zero-value checksum into the verifier.

Related errors


AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15). Data as JSON: /api/errors/09a685921e34abdf. Report an issue: GitHub.