jdx/mise · error
multiple tools specified, use --all to uninstall all version
Error message
multiple tools specified, use --all to uninstall all versions
What it means
`mise uninstall` matched multiple versions (of one or more tools) but `--all` was not passed, so mise refuses to guess which versions to remove. The guard fires when the deduplicated tool/version set is larger than the number of explicitly named tools.
Source
Thrown at src/cli/uninstall.rs:72
impl Uninstall {
pub(super) fn is_dry_run(&self) -> bool {
self.dry_run || self.dry_run_code
}
pub(crate) async fn run(self) -> Result<()> {
let config = Config::get().await?;
let tool_versions = if self.installed_tool.is_empty() && self.all {
self.get_all_tool_versions(&config).await?
} else {
self.get_requested_tool_versions(&config).await?
};
let tool_versions = tool_versions
.into_iter()
.unique_by(|(_, tv)| (tv.request.ba().short.clone(), tv.version.clone()))
.collect::<Vec<_>>();
if !self.all && tool_versions.len() > self.installed_tool.len() {
bail!("multiple tools specified, use --all to uninstall all versions");
}
let removed_install_paths = tool_versions
.iter()
.map(|(_, tv)| tv.install_path())
.collect::<Vec<_>>();
let mpr = MultiProgressReport::get();
let mut to_remove = Vec::with_capacity(tool_versions.len());
for (plugin, tv) in tool_versions {
// `is_version_installed` resolves the install path, so it says no for a link whose
// target is gone -- and that entry is precisely what someone running `uninstall` is
// trying to get rid of. Refusing it left the name occupied with no command able to
// free it. It is still not *installed*: this only decides whether there is something
// here to remove.
if !plugin.is_version_installed(&config, &tv, true)
&& !file::entry_exists(tv.install_path())
{
warn!("{} is not installed", tv.style());View on GitHub (pinned to afd2eddd3a)
Solutions
- Pass `--all` to uninstall all installed versions: `mise uninstall node --all`.
- Specify the exact version: `mise uninstall node@20.1.0`.
- List installed versions with `mise ls node` to decide which to remove.
Example fix
// before mise uninstall node // after mise uninstall node --all # or mise uninstall node@20.1.0
Defensive patterns
Strategy: validation
Validate before calling
[ "$(mise ls node --json | jq 'length')" -gt 1 ] && mise uninstall node --all || mise uninstall node
Prevention
- Check `mise ls <tool>` for multiple versions before uninstalling.
- Always pass an explicit version or --all in scripts.
- Avoid bare `mise uninstall <tool>` in automation.
When it happens
Trigger: Running `mise uninstall <tool>` (no version suffix) when more than one version of the tool is installed, without `--all`, in run().
Common situations: A tool has accumulated several installed versions; user runs `mise uninstall node` expecting removal of the active one only or all — mise demands explicitness via --all or an explicit version.
Understand the failure class
Background: "--flag is required" and "must specify" CLI errors: how missing-required-flag validation works and how to fix it — this error's family across 20 libraries.
Related errors
- {name} does not support declarative package removal
- package plugin '{}' does not support uninstall; add hooks/pa
- failed to uninstall {tv}
- {}@{requested} is not installed{resolved} hint: run `mise in
- No executable found for configured tool: {bin_name} The inst
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/f4b4d1b09b7b4c06.
Report an issue: GitHub.