{"record":{"id":"3224c9abb48e91f1","repo":"helm/helm","slug":"failed-to-save-tarball-w-3224c9","errorCode":null,"errorMessage":"failed to save tarball: %w","messagePattern":"failed to save tarball: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/plugin/installer/local_installer.go","lineNumber":124,"sourceCode":"\t// Read the archive file\n\tdata, err := os.ReadFile(i.Source)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to read archive: %w\", err)\n\t}\n\n\t// Copy the original tarball to plugins directory for verification\n\t// Extract metadata to get the actual plugin name and version\n\tmetadata, err := plugin.ExtractTgzPluginMetadata(bytes.NewReader(data))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to extract plugin metadata from tarball: %w\", err)\n\t}\n\tfilename := fmt.Sprintf(\"%s-%s.tgz\", metadata.Name, metadata.Version)\n\ttarballPath := helmpath.DataPath(\"plugins\", filename)\n\tif err := os.MkdirAll(filepath.Dir(tarballPath), 0o755); err != nil {\n\t\treturn fmt.Errorf(\"failed to create plugins directory: %w\", err)\n\t}\n\tif err := os.WriteFile(tarballPath, data, 0o644); err != nil {\n\t\treturn fmt.Errorf(\"failed to save tarball: %w\", err)\n\t}\n\n\t// Check for and copy .prov file if it exists\n\tprovSource := i.Source + \".prov\"\n\tif provData, err := os.ReadFile(provSource); err == nil {\n\t\tprovPath := tarballPath + \".prov\"\n\t\tif err := os.WriteFile(provPath, provData, 0o644); err != nil {\n\t\t\tslog.Debug(\"failed to save provenance file\", \"error\", err)\n\t\t}\n\t}\n\n\t// Create a temporary directory for extraction\n\ttempDir, err := os.MkdirTemp(\"\", \"helm-plugin-extract-\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create temp directory: %w\", err)\n\t}\n\tdefer os.RemoveAll(tempDir)\n","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/helm/helm/blob/2a29f1770b62844b27197d2507377361d45ad7c0/internal/plugin/installer/local_installer.go#L106-L142","documentation":"After extracting metadata, LocalInstaller writes the original tarball bytes to <HELM_DATA_HOME>/plugins/<name>-<version>.tgz so future --verify runs have the exact artifact; os.WriteFile on that path failed. Causes: the plugins data directory is not writable, a leftover directory (not file) already exists at that exact filename, or the filesystem is full.","triggerScenarios":"A previous partial install left a directory named myplugin-1.0.0.tgz in the plugins data dir; plugins dir owned by root after running Helm under sudo; ENOSPC; two different plugins colliding on the same name-version filename.","commonSituations":"Switching between sudo helm and plain helm (root-owned state); CI runners with tiny disks; uninstalling a plugin manually (rm -rf of the dir but not the saved tarball) leaving inconsistent state.","solutions":["Check the target: ls -la $(helm env HELM_DATA_HOME)/plugins/myplugin-1.0.0.tgz — if it is a directory, remove it","Fix ownership of the plugins data dir: chown -R $(id -u):$(id -g) <data>/plugins or avoid mixing sudo and non-sudo Helm","Free disk space if the volume is full (df -h)","Retry the install after cleaning the colliding entry"],"exampleFix":"# before: leftover directory blocks the tarball path\nls -d ~/.local/share/helm/plugins/myplugin-1.0.0.tgz/  # it's a dir\n# after: remove collision, reinstall\nrm -rf ~/.local/share/helm/plugins/myplugin-1.0.0.tgz && helm plugin install ./myplugin-1.0.0.tgz","handlingStrategy":"validation","validationCode":"func tarballSlotFree(name, version string) error {\n\ttarget := helmpath.DataPath(\"plugins\", fmt.Sprintf(\"%s-%s.tgz\", name, version))\n\tif fi, err := os.Lstat(target); err == nil && fi.IsDir() {\n\t\treturn fmt.Errorf(\"a directory occupies %s — remove it first\", target)\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["After manual plugin removals, also clean <data>/plugins/<name>-<version>.tgz to avoid collisions","Keep one owning user for the Helm data dir","Monitor disk space on the data volume in CI"],"tags":["go","helm","filesystem","permissions","disk-full","state-collision"],"backgroundTag":null,"analyzedSha":"2a29f1770b62844b27197d2507377361d45ad7c0","analyzedAt":"2026-08-15T22:02:47.490Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}