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

  1. Treat it as non-fatal: verify with `mise ls` and manually remove the old version with `mise uninstall <tool>@<old-version>`.
  2. Close processes using the old install path and re-run `mise upgrade` or `mise uninstall`.
  3. Check the warned cause for permission issues and fix ownership of the installs directory.
  4. 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

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


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/073e033d562efdc3. Report an issue: GitHub.