{"record":{"id":"cc56af2d58dcf493","repo":"jdx/mise","slug":"package-plugin-does-not-support-uninstall-ad","errorCode":null,"errorMessage":"package plugin '{}' does not support uninstall; add hooks/package_uninstall.lua","messagePattern":"package plugin '(.+?)' does not support uninstall; add hooks/package_uninstall\\.lua","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/system/prune.rs","lineNumber":100,"sourceCode":"            bail!(\"{} is not available: {reason}\", self.manager);\n        }\n        let manager = PackagePluginManager::new(self.manager.clone())?;\n        let config = Config::get().await?;\n        let configured = system::package_requests_for_manager_from_config_and_tracked_config_files(\n            &config,\n            &self.manager,\n        )\n        .await?;\n        let plan = manager.prune_plan(&configured).await?;\n        if plan.is_empty() {\n            if !self.dry_run {\n                manager.apply_prune_plan(&plan).await?;\n            }\n            info!(\"{}: nothing to prune\", self.manager);\n            return Ok(());\n        }\n        if !manager.supports_uninstall() {\n            bail!(\n                \"package plugin '{}' does not support uninstall; add hooks/package_uninstall.lua\",\n                self.manager\n            );\n        }\n        let remove = plan\n            .remove\n            .iter()\n            .map(ToString::to_string)\n            .collect::<Vec<_>>();\n        if self.dry_run {\n            for package in &remove {\n                miseprintln!(\"remove {}:{package}\", self.manager);\n            }\n            return Ok(());\n        }\n        if !self.yes && !Settings::get().yes && console::user_attended_stderr() {\n            let msg = format!(\"{}: prune {}?\", self.manager, remove.join(\", \"));\n            if !prompt::confirm(msg)?.is_yes() {","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/cli/system/prune.rs#L82-L118","documentation":"After computing a prune plan with removable packages, run_plugin checks `manager.supports_uninstall()`. A plugin that lacks `hooks/package_uninstall.lua` cannot perform removals, so mise bails instead of leaving the plan partially applied. The error names the exact missing hook file.","triggerScenarios":"Running `mise system prune --manager <plugin>` where the plugin has install hooks but no `package_uninstall.lua`, and the computed plan contains packages to remove.","commonSituations":"Third-party vfox plugins that only implement install; hand-written plugins missing the uninstall hook; plugin updated upstream dropping the uninstall hook.","solutions":["Add a `hooks/package_uninstall.lua` hook to the plugin and implement package removal.","Remove the packages the plan targets manually via the manager's own CLI.","Switch to a plugin that supports uninstall.","Report/request uninstall support upstream for the plugin."],"exampleFix":"// before: plugin directory lacks the hook\nplugins/myplugin/hooks/install.lua\n// after\nplugins/myplugin/hooks/install.lua\nplugins/myplugin/hooks/package_uninstall.lua  -- implement removal for the given package request","handlingStrategy":"validation","validationCode":"test -f ~/.local/share/mise/plugins/myplugin/hooks/package_uninstall.lua && echo ok || echo \"plugin cannot uninstall\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Require hooks/package_uninstall.lua when adopting third-party plugins you intend to prune.","Add the uninstall hook to in-house plugins at creation time.","Check plugin hook inventory before relying on prune."],"tags":["cli","system-packages","prune","plugin","uninstall"],"backgroundTag":"method-not-implemented","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}