{"record":{"id":"799862b73fd239a4","repo":"larksuite/cli","slug":"tar-w","errorCode":null,"errorMessage":"tar: %w","messagePattern":"tar: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shortcuts/apps/plugin_common.go","lineNumber":367,"sourceCode":"// pluginExtractTGZ extracts a gzipped tar archive into destDir, stripping the\n// first path component (npm convention: tarballs contain a \"package/\" prefix).\n// Path traversal entries are silently skipped.\nfunc pluginExtractTGZ(r io.Reader, destDir string) error {\n\tgz, err := gzip.NewReader(r)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"gzip: %w\", err) //nolint:forbidigo // intermediate helper error; callers wrap as typed\n\t}\n\tdefer gz.Close()\n\n\tcleanDest := filepath.Clean(destDir) + string(filepath.Separator)\n\ttr := tar.NewReader(gz)\n\tfor {\n\t\thdr, err := tr.Next()\n\t\tif err == io.EOF {\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"tar: %w\", err) //nolint:forbidigo // intermediate helper error; callers wrap as typed\n\t\t}\n\n\t\tname := pluginStripFirstComponent(hdr.Name)\n\t\tif name == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tif strings.Contains(name, \"..\") {\n\t\t\tcontinue\n\t\t}\n\n\t\ttarget := filepath.Join(destDir, name)\n\t\tif !strings.HasPrefix(filepath.Clean(target)+string(filepath.Separator), cleanDest) &&\n\t\t\tfilepath.Clean(target) != filepath.Clean(destDir) {\n\t\t\tcontinue\n\t\t}\n\n\t\tswitch hdr.Typeflag {\n\t\tcase tar.TypeSymlink, tar.TypeLink:","sourceCodeStart":349,"sourceCodeEnd":385,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/apps/plugin_common.go#L349-L385","documentation":"pluginExtractTGZ wraps tar.Reader.Next failures with 'tar: %w'. The gzip layer succeeded but the tar stream is corrupt, truncated, or contains unreadable headers, so extraction aborts. It is an intermediate error; callers wrap it as typed.","triggerScenarios":"A gzip-valid but non-tar payload (e.g. gzip of a plain file), a truncated tarball, or a tarball with malformed headers fed to plugin install.","commonSituations":"Renaming a .gz (single file) to .tgz, partial downloads, or archives produced by broken tooling.","solutions":["Verify the payload is a real tarball: `tar -tzf plugin.tgz` should list package/... entries","Re-download or re-pack the archive (`tar -czf`) and retry the install","Check the download completed fully (compare byte size/checksum)"],"exampleFix":"// before\ngzip -9 plugin.js && mv plugin.js.gz plugin.tgz  # not a tarball\n// after\ntar -czf plugin.tgz --transform 's,^,package/,' plugin.js","handlingStrategy":"validation","validationCode":"// sanity-check the archive lists a package/ prefix before installing\n// tar -tzf plugin.tgz | head  ->  expect \"package/...\" entries","typeGuard":null,"tryCatchPattern":"if strings.HasPrefix(err.Error(), \"tar: \") {\n\t// the payload passed gzip but not tar: re-download or re-pack as a real tarball\n}","preventionTips":["Only pass real .tar.gz archives, never renamed .gz single files","Compare downloaded byte size/checksum against the published artifact","Test with `tar -tzf` before installing"],"tags":["archive","tar","plugin-install"],"backgroundTag":"corrupt-tar-archive","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}