{"record":{"id":"40fb8c3a6a23e2a0","repo":"multica-ai/multica","slug":"read-tar-w","errorCode":null,"errorMessage":"read tar: %w","messagePattern":"read tar: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/internal/cli/update.go","lineNumber":497,"sourceCode":"}\n\n// extractBinaryFromTarGz reads a .tar.gz stream and returns the contents of the\n// named file entry.\nfunc extractBinaryFromTarGz(r io.Reader, name string) ([]byte, error) {\n\tgz, err := gzip.NewReader(r)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"gzip reader: %w\", err)\n\t}\n\tdefer gz.Close()\n\n\ttr := tar.NewReader(gz)\n\tfor {\n\t\thdr, err := tr.Next()\n\t\tif err == io.EOF {\n\t\t\treturn nil, fmt.Errorf(\"binary %q not found in archive\", name)\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"read tar: %w\", err)\n\t\t}\n\t\t// Match the binary name (may be prefixed with a directory).\n\t\tif filepath.Base(hdr.Name) == name && hdr.Typeflag == tar.TypeReg {\n\t\t\tdata, err := io.ReadAll(tr)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"read binary: %w\", err)\n\t\t\t}\n\t\t\treturn data, nil\n\t\t}\n\t}\n}\n\n// extractBinaryFromZip reads a .zip stream and returns the contents of the\n// named file entry. The zip format requires random access, so the full archive\n// is buffered in memory.\nfunc extractBinaryFromZip(r io.Reader, name string) ([]byte, error) {\n\tbuf, err := io.ReadAll(r)\n\tif err != nil {","sourceCodeStart":479,"sourceCodeEnd":515,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/internal/cli/update.go#L479-L515","documentation":"tar.Next failed with a non-EOF error while scanning the tar stream; wrapped as 'read tar: %w'. Since the gzip header parsed and the SHA-256 matched the manifest, this indicates structurally invalid tar data (bad header checksum, unsupported typeflag, truncation inside a supposedly verified body).","triggerScenarios":"A tar built with extensions/pax features or a format variant Go's archive/tar rejects; truncation that still matched the manifest because the manifest was computed over the truncated file; hand-crafted archives with incorrect headers.","commonSituations":"Custom packaging scripts producing non-ustar/GNU headers; a release asset truncated at upload time so checksums.txt describes the truncated bytes; mixing tar implementations across build machines.","solutions":["Verify the archive opens with system tar (`tar -tzf asset.tar.gz`) to distinguish Go-rejected formats from real corruption.","Rebuild the archive with a standard tool (GNU tar, GoReleaser defaults).","If the asset was truncated at upload, re-run the release upload so checksums.txt matches the complete file.","Report the wrapped error text — tar names the precise header problem."],"exampleFix":"null","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":"data, err := extractBinaryFromTarGz(r, \"multica\")\nif err != nil && strings.HasPrefix(err.Error(), \"read tar\") {\n    // structurally invalid tar (verified checksum): rebuild archive with standard tooling\n}","preventionTips":["Build archives with GNU tar or GoReleaser defaults, not ad-hoc scripts","Verify archives extract cleanly in release CI","Re-upload complete files if uploads were interrupted"],"tags":["tar","archive","corruption","extraction"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}