{"record":{"id":"0999c99de172400c","repo":"jdx/mise","slug":"does-not-support-declarative-package-removal","errorCode":null,"errorMessage":"{} does not support declarative package removal","messagePattern":"(.+?) does not support declarative package removal","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/packages/mod.rs","lineNumber":205,"sourceCode":"    /// This is *availability*, not installed state — [`Self::installed`]\n    /// cannot answer it (apt's asks dpkg, which only knows what is already on\n    /// the box). Used to resolve a plugin's candidate package names, where the\n    /// same capability is packaged under different names across distro\n    /// releases. Must be side-effect free and never elevate.\n    ///\n    /// The default reports every name as available, which makes candidate\n    /// resolution pick the first one — the behavior before candidate lists\n    /// existed. Managers override it where the query is cheap.\n    async fn available(&self, names: &[String]) -> Result<Vec<bool>> {\n        Ok(vec![true; names.len()])\n    }\n\n    /// Install the given packages (already filtered to missing, mismatched, or repairable).\n    async fn install(&self, pkgs: &[PackageRequest], opts: &InstallOpts) -> Result<()>;\n\n    /// Remove packages declared with `state = \"absent\"`.\n    async fn remove(&self, _pkgs: &[PackageRequest], _opts: &InstallOpts) -> Result<()> {\n        eyre::bail!(\n            \"{} does not support declarative package removal\",\n            self.name()\n        )\n    }\n\n    fn supports_remove(&self) -> bool {\n        false\n    }\n\n    /// Install with manager-specific declarative options. Managers without\n    /// additional package options use the ordinary install path unchanged.\n    async fn install_with_options(\n        &self,\n        pkgs: &[PackageRequest],\n        opts: &InstallOpts,\n        _manager_options: &ManagerPackageOptions,\n    ) -> Result<()> {\n        self.install(pkgs, opts).await","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/packages/mod.rs#L187-L223","documentation":"The package provider trait's default remove() is intentionally unimplemented: providers that cannot declaratively uninstall (such as mas, where App Store apps aren't removed via install/uninstall symmetry) hit this default and bail naming the provider. The caller attempted `state = \"absent\"` for a backend lacking removal support.","triggerScenarios":"Declaring a package with `state = \"absent\"` for a provider whose supports_remove() is false, so the trait's default remove() runs and immediately fails with the provider name in the message.","commonSituations":"Users migrating an Ansible-style declarative package manifest to mise and marking Mac App Store apps absent; removing packages from a config without checking provider capabilities.","solutions":["Remove the `state = \"absent\"` declaration for packages from this provider","Uninstall the app manually (e.g. via Launchpad/Finder for mas apps)","Use a provider that supports removal for that package if declarative removal is required","Check supports_remove()/docs to learn which providers support absent state"],"exampleFix":"// before\n[[packages]]\nprovider = \"mas\"\nname = \"497799835\"\nstate = \"absent\"\n// after: uninstall manually; keep config limited to present-state mas apps\n[[packages]]\nprovider = \"mas\"\nname = \"497799835\"","handlingStrategy":"validation","validationCode":"if pkg.state == Absent && !provider.supports_remove() {\n    eprintln!(\"provider {} cannot remove packages; handle manually\", provider.name());\n}","typeGuard":null,"tryCatchPattern":"match provider.remove(&absent, &opts).await {\n    Err(e) if e.to_string().contains(\"does not support declarative package removal\") => {\n        eprintln!(\"skipping: uninstall these packages manually\");\n    }\n    other => other?,\n}","preventionTips":["Check supports_remove() before declaring absent state","Keep mas entries present-only and uninstall App Store apps by hand","Route removals through providers that implement remove()"],"tags":["package-manager","unsupported-operation","declarative"],"backgroundTag":"unsupported-operation","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"}