{"record":{"id":"0a1811d581345251","repo":"helm/helm","slug":"failed-to-uninstall-plugin-s-got-error-w","errorCode":null,"errorMessage":"failed to uninstall plugin %s, got error (%w)","messagePattern":"failed to uninstall plugin (.+?), got error \\(%w\\)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/cmd/plugin_uninstall.go","lineNumber":73,"sourceCode":"func (o *pluginUninstallOptions) complete(args []string) error {\n\tif len(args) == 0 {\n\t\treturn errors.New(\"please provide plugin name to uninstall\")\n\t}\n\to.names = args\n\treturn nil\n}\n\nfunc (o *pluginUninstallOptions) run(out io.Writer) error {\n\tslog.Debug(\"loading installer plugins\", \"dir\", settings.PluginsDirectory)\n\tplugins, err := plugin.LoadAllDir(settings.PluginsDirectory, plugin.LogIgnorePluginLoadErrorFilterFunc)\n\tif err != nil {\n\t\treturn err\n\t}\n\tvar errorPlugins []error\n\tfor _, name := range o.names {\n\t\tif found := findPlugin(plugins, name); found != nil {\n\t\t\tif err := uninstallPlugin(found); err != nil {\n\t\t\t\terrorPlugins = append(errorPlugins, fmt.Errorf(\"failed to uninstall plugin %s, got error (%w)\", name, err))\n\t\t\t} else {\n\t\t\t\tfmt.Fprintf(out, \"Uninstalled plugin: %s\\n\", name)\n\t\t\t}\n\t\t} else {\n\t\t\terrorPlugins = append(errorPlugins, fmt.Errorf(\"plugin: %s not found\", name))\n\t\t}\n\t}\n\tif len(errorPlugins) > 0 {\n\t\treturn errors.Join(errorPlugins...)\n\t}\n\treturn nil\n}\n\nfunc uninstallPlugin(p plugin.Plugin) error {\n\tif err := os.RemoveAll(p.Dir()); err != nil {\n\t\treturn err\n\t}\n","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/helm/helm/blob/2a29f1770b62844b27197d2507377361d45ad7c0/pkg/cmd/plugin_uninstall.go#L55-L91","documentation":"`helm plugin uninstall NAME...` removes each plugin's directory with os.RemoveAll, deletes cached versioned tarballs, and runs the plugin's delete hook (pkg/cmd/plugin_uninstall.go:87-122). Any per-plugin failure is collected and the batch is returned via errors.Join, so one bad plugin does not stop the others but the command still fails overall. Note a missing plugin produces the distinct 'plugin: %s not found' error instead.","triggerScenarios":"Plugins directory owned by root while running as a normal user (os.RemoveAll permission denied); a file inside the plugin dir held open (Windows locks, running plugin process); the plugin's delete hook script exiting non-zero.","commonSituations":"Plugin installed with sudo but uninstalled without; manually placed plugins with odd ownership; antivirus or editors locking shared libraries during removal.","solutions":["Fix ownership of the plugins directory (sudo chown -R $(id -u):$(id -g) $HELM_PLUGINS) or re-run the uninstall with sudo","If the directory is stuck, remove it manually (rm -rf $HELM_PLUGINS/<name>) and confirm with `helm plugin list`","For hook failures, inspect the plugin's delete hook script and run it manually to see its error"],"exampleFix":"# before\nhelm plugin uninstall my-plugin\n# error: failed to uninstall plugin my-plugin, got error (unlinkat ...: permission denied)\n\n# after\nsudo chown -R \"$(id -u):$(id -g)\" \"$(helm env HELM_PLUGINS)\"\nhelm plugin uninstall my-plugin","handlingStrategy":"try-catch","validationCode":"func canRemovePluginDir(dir string) error {\n    fi, err := os.Stat(dir)\n    if err != nil {\n        return err\n    }\n    if !fi.IsDir() {\n        return nil\n    }\n    probe := filepath.Join(dir, \".rm-probe\")\n    if err := os.WriteFile(probe, nil, 0o644); err != nil {\n        return fmt.Errorf(\"no write access to %s (owned by another user?): %w\", dir, err)\n    }\n    return os.Remove(probe)\n}","typeGuard":null,"tryCatchPattern":"if err := runPluginUninstall(names); err != nil {\n    // errors.Join bundles per-plugin failures; split them for reporting\n    type unwrapper interface{ Unwrap() []error }\n    if u, ok := err.(unwrapper); ok {\n        for _, e := range u.Unwrap() {\n            log.Print(e) // handle each plugin independently (permissions vs not-found vs hook)\n        }\n    }\n    return err\n}","preventionTips":["Install and uninstall plugins as the same user so the plugins directory stays owned by that user","On Windows, stop processes using plugin binaries before uninstalling","Test delete hooks before shipping a plugin; a failing hook fails the whole uninstall"],"tags":["plugins","uninstall","filesystem","permissions"],"backgroundTag":null,"analyzedSha":"2a29f1770b62844b27197d2507377361d45ad7c0","analyzedAt":"2026-08-15T22:02:47.490Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}