jdx/mise · warning
Failed to uninstall old version of {}: {}
Error message
Failed to uninstall old version of {}: {} What it means
During `mise upgrade`, after installing the new version, mise attempts to uninstall the previous version via `uninstall_old_version`. If that cleanup fails it logs "Failed to uninstall old version of {tool}: {cause}" with `warn!` — the upgrade itself succeeded; only the old-version cleanup failed, so execution continues.
Source
Thrown at src/cli/upgrade.rs:716
.map(|tv| (format!("{}@{}", tv.ba().short, tv.version), tv.style())),
);
for old_tv in immediate {
let key = format!("{}@{}", old_tv.ba().short, old_tv.version);
let tool = progress
.as_ref()
.and_then(|progress| progress.start_tool(&key));
let pr = match &tool {
Some(tool) => tool.reporter(),
None => mpr.add(&format!("uninstall {}", old_tv.style())),
};
let result = self
.uninstall_old_version(config, &old_tv, pr.as_ref())
.await;
if let Some(tool) = &tool {
tool.complete(result.as_ref().err().map(|e| e.to_string()).as_deref());
}
match result {
Err(e) => warn!(
"Failed to uninstall old version of {}: {}",
old_tv.ba().short,
e
),
Ok(()) => {
if let Err(err) = crate::tool_purgatory::forget_path(&old_tv.install_path())
{
warn!("failed to clear tool purgatory entry: {err:#}");
}
}
}
}
if let Some(progress) = progress.as_mut() {
progress.finish(vec![]);
}
}
mpr.finish_progress();View on GitHub (pinned to afd2eddd3a)
Solutions
- Treat it as non-fatal: verify with `mise ls` and manually remove the old version with `mise uninstall <tool>@<old-version>`.
- Close processes using the old install path and re-run `mise upgrade` or `mise uninstall`.
- Check the warned cause for permission issues and fix ownership of the installs directory.
- Ignore if the old version was already gone — cleanup is best-effort.
Example fix
// before mise upgrade node # warns: Failed to uninstall old version of node: ... // after mise uninstall node@20.0.0 # remove stale version manually mise ls
Defensive patterns
Strategy: try-catch
Validate before calling
mise ls <tool> # check installed versions before upgrading
Try / catch
let out = Command::new("mise").args(["upgrade", tool]).output()?;
if !out.status.success() || String::from_utf8_lossy(&out.stderr).contains("Failed to uninstall old version") {
// non-fatal: manually clean the old version
Command::new("mise").args(["uninstall", &format!("{tool}@{old}")]).status()?;
} Prevention
- Treat upgrade cleanup warnings as non-fatal and reconcile with `mise ls`.
- Stop running tool binaries before upgrading.
- Keep install directories writable and untouched by external tooling.
When it happens
Trigger: `mise upgrade <tool>` where the new version installs fine but removing the old install path fails (locked files, permission issues, or the `tool_purgatory::forget_path` cleanup after removal errors).
Common situations: Old version's binary still running during upgrade; manually deleted old install dirs leaving inconsistent state; Windows file locking; disk/permission problems.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- mise upgrade --monorepo is not implemented yet
- cannot upgrade {} because no configured tools were resolved
- cannot upgrade {} because not every request binding was reso
- invalid command wrapper name: {name:?}
- failed to uninstall {tv}
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/073e033d562efdc3.
Report an issue: GitHub.