Skip to content

fix: Rust channel updates installing twice#7565

Merged
jdx merged 2 commits into
jdx:mainfrom
rjvkn:main
Jan 7, 2026
Merged

fix: Rust channel updates installing twice#7565
jdx merged 2 commits into
jdx:mainfrom
rjvkn:main

Conversation

@rjvkn
Copy link
Copy Markdown

@rjvkn rjvkn commented Jan 4, 2026

Summary

This PR fixes an issue in the upgrade flow where channel-based versions were being uninstalled twice during upgrade when the resolved version did not change.

The change is intentionally minimal and only removes the final unnecessary uninstall step.


Current behavior

For channel-based versions (i.e. versions that resolve to the same string on upgrade), mise currently performs:

  1. Uninstall existing version
  2. Install resolved version
  3. Uninstall again (incorrect)

The last uninstall is redundant and can remove the freshly installed tool.


Fix

Skip the final uninstall step when the currently installed version string is identical to the resolved latest version string.

if &o.latest == current {
    return None;
}

Scope

  • Affects channel-based upgrades where current == latest
  • Prevents a redundant uninstall
  • No behavior change for versioned upgrades
  • No backend or command changes

Note

While working on this, I initially explored using tool-specific update commands for channel-based upgrades instead of the uninstall/reinstall flow, using rust tool as a pilot.

Even with relatively small changes, that approach increased complexity and made the code harder to reason about. To keep this PR focused, readable, and easy to review, I decided to keep this minimal fix separate and revisit a cleaner, more general approach in a follow-up.


Follow-up

A future PR could explore a cleaner and more generalized upgrade strategy for channel-based versions, but that work is intentionally out of scope for this fix.


Note

Prevents double-uninstall during upgrades of channel-based versions that resolve in-place.

  • Adjusts to_remove computation in upgrade.rs to skip uninstall when o.current equals o.latest (e.g., nightly, stable, beta)
  • Dry-run output now omits the unnecessary uninstall line for these cases
  • No changes to install flow, config bumping, or other tool behaviors

Written by Cursor Bugbot for commit 41ac56d. This will update automatically on new commits. Configure here.

@rjvkn rjvkn changed the title Fix: Rust channel updates installing twice fix: Rust channel updates installing twice Jan 4, 2026
Copy link
Copy Markdown
Contributor

@roele roele left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great contribution! This topic came up a couple times already.

Only improvement/nitpick i see is that conditional use of the CmdLineRunner could be simplified a bit.

Comment thread src/plugins/core/rust.rs Outdated
@rjvkn
Copy link
Copy Markdown
Author

rjvkn commented Jan 4, 2026

Great contribution! This topic came up a couple times already.

Only improvement/nitpick i see is that conditional use of the CmdLineRunner could be simplified a bit.

Great suggestion! This eliminates the duplication nicely. Will update.

@jdx
Copy link
Copy Markdown
Owner

jdx commented Jan 4, 2026

Bugbot run

Comment thread src/plugins/core/rust.rs Outdated
runner = runner.arg("toolchain").arg("install");
}

runner
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rustup update called with unsupported command-line flags

When a channel (nightly/stable/beta) is already installed, the code now uses rustup update instead of rustup toolchain install. However, the command still appends --profile, --component, and --target arguments which are only valid for rustup toolchain install. If users have a rust-toolchain.toml with profile, components, or targets configured, the rustup update command will fail with unknown argument errors. The conditional should also exclude these arguments when using the update subcommand.

Fix in Cursor Fix in Web

Comment thread src/plugins/core/rust.rs Outdated
.arg("install")
let mut runner = CmdLineRunner::new(RUSTUP_BIN).with_pr(ctx.pr.as_ref());

if self.is_channel(&tv) && tv.install_path().exists() {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Install path check incorrect due to pre-created directory

The condition tv.install_path().exists() always evaluates to true for channel installs because the base install_version method calls create_install_dirs before invoking install_version_, which creates an empty directory at the install path. This means the code uses rustup update instead of rustup toolchain install even for fresh channel installations or force reinstalls where the toolchain was just uninstalled. The check was intended to detect if a channel is already installed in rustup, but it actually detects whether the mise install directory exists (which is always true at this point in the flow).

Fix in Cursor Fix in Web

@rjvkn rjvkn marked this pull request as draft January 5, 2026 07:10
@rjvkn rjvkn closed this Jan 5, 2026
@rjvkn rjvkn reopened this Jan 5, 2026
@rjvkn rjvkn requested a review from roele January 5, 2026 15:09
@rjvkn rjvkn marked this pull request as ready for review January 5, 2026 15:09
@rjvkn
Copy link
Copy Markdown
Author

rjvkn commented Jan 5, 2026

@jdx @roele I updated the scope of this PR to keep it strictly focused on fixing the redundant uninstall for channel-based upgrades when the resolved version doesn’t change.

I moved the broader “use update commands instead of uninstall/reinstall” idea out of this PR and will revisit it separately with a cleaner, more general approach.

@jdx
Copy link
Copy Markdown
Owner

jdx commented Jan 5, 2026

bugbot run

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no bugs!

@jdx jdx merged commit c83454a into jdx:main Jan 7, 2026
32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants