{"record":{"id":"4da8a45a0a0aa4c1","repo":"multica-ai/multica","slug":"read-checksum-manifest-w","errorCode":null,"errorMessage":"read checksum manifest: %w","messagePattern":"read checksum manifest: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/internal/cli/update.go","lineNumber":207,"sourceCode":"func parseChecksumManifest(manifest []byte, assetName string) (string, error) {\n\tscanner := bufio.NewScanner(bytes.NewReader(manifest))\n\tfor scanner.Scan() {\n\t\tline := strings.TrimSpace(scanner.Text())\n\t\tif line == \"\" || strings.HasPrefix(line, \"#\") {\n\t\t\tcontinue\n\t\t}\n\t\tfields := strings.Fields(line)\n\t\t// GoReleaser's default separator is two spaces; some tools use one\n\t\t// or pad with tabs. strings.Fields handles all of those at once.\n\t\tif len(fields) < 2 {\n\t\t\tcontinue\n\t\t}\n\t\tif fields[1] == assetName {\n\t\t\treturn strings.ToLower(fields[0]), nil\n\t\t}\n\t}\n\tif err := scanner.Err(); err != nil {\n\t\treturn \"\", fmt.Errorf(\"read checksum manifest: %w\", err)\n\t}\n\treturn \"\", fmt.Errorf(\"checksum for %q not found in manifest\", assetName)\n}\n\n// verifyAssetSHA256 returns nil when the SHA-256 of data matches the lowercase\n// hex expected value, or an error otherwise. The error includes both digests\n// so a corrupted asset is diagnosable from the log without re-downloading.\nfunc verifyAssetSHA256(data []byte, expectedHex, assetName string) error {\n\tif expectedHex == \"\" {\n\t\treturn fmt.Errorf(\"empty expected checksum for %q\", assetName)\n\t}\n\tsum := sha256.Sum256(data)\n\tactual := hex.EncodeToString(sum[:])\n\tif !strings.EqualFold(actual, expectedHex) {\n\t\treturn fmt.Errorf(\"checksum mismatch for %q: expected %s, got %s\", assetName, expectedHex, actual)\n\t}\n\treturn nil\n}","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/internal/cli/update.go#L189-L225","documentation":"parseChecksumManifest got an I/O error from its bufio.Scanner while reading the downloaded checksums.txt — i.e. the manifest bytes were malformed in a way the scanner surfaced as an error, classically a line longer than the 64KB scanner buffer limit.","triggerScenarios":"A checksums.txt containing an extremely long line (generated garbage, HTML error page saved as the manifest, or a binary blob uploaded under the checksums.txt name) makes bufio.Scanner return ErrTooLong.","commonSituations":"A proxy or mirror serving an HTML login page in place of checksums.txt; corrupted download truncation producing one massive line; a misconfigured release job concatenating binaries into the manifest.","solutions":["Download checksums.txt manually and inspect it — verify it is plain '<sha256>  <filename>' lines","Re-fetch the release from the official repo to rule out mirror/proxy corruption","If you generate the manifest, ensure one checksum per line with standard formatting","Re-publish the release with a correctly generated manifest"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if len(manifest) > 0 && bytes.ContainsRune(manifest[:min(len(manifest),1024)], '<') {\n\t// looks like an HTML error page, not a checksum manifest; refetch\n}","typeGuard":null,"tryCatchPattern":"sum, err := cli.ParseChecksumManifest(manifest, assetName) // or equivalent\nif err != nil && strings.Contains(err.Error(), \"read checksum manifest\") {\n\t// scanner-level failure: refetch the manifest once, then give up\n}","preventionTips":["Download checksums.txt from the official repo, not mirrors","Sanity-check the manifest's first bytes are hex digests, not HTML","Regenerate manifests mechanically; never hand-edit them"],"tags":["checksum","release","parsing","io","go"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}