fix(upgrade): respect use_locked_version when checking tracked configs#7997
fix(upgrade): respect use_locked_version when checking tracked configs#7997
Conversation
When checking which versions are needed by tracked configs during upgrade, the code was always using the lockfile to resolve versions even when use_locked_version was explicitly set to false. This caused old versions to be incorrectly kept after upgrade because the lockfile hadn't been updated yet. The root cause was in ToolVersionList::resolve which overrode use_locked_version to true for non-"latest" versions, ignoring the caller's setting. Fixes #7991 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes a bug where mise upgrade incorrectly kept old versions when lockfile was enabled, even when those versions were no longer needed by tracked configs.
Changes:
- Modified version resolution logic to respect the caller's
use_locked_versionsetting instead of always forcing it totrue - Updated
get_versions_needed_by_tracked_configsto explicitly useuse_locked_version: falsewhen checking what versions are needed - Added e2e test to verify old versions are correctly pruned after upgrade with lockfile enabled
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/toolset/tool_version_list.rs | Updated version resolution to respect caller's use_locked_version setting instead of overriding it |
| src/toolset/mod.rs | Modified tracked config version checking to explicitly disable lockfile usage during upgrade |
| e2e/lockfile/test_lockfile_upgrade_prune | Added regression test verifying old versions are removed after upgrade with lockfile enabled |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Summary of ChangesHello @jdx, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request resolves a critical bug in Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request correctly addresses a bug in mise upgrade where old tool versions were not being uninstalled when a lockfile was in use. The changes are logical and well-implemented: get_versions_needed_by_tracked_configs now correctly ignores the lockfile, and ToolVersionList::resolve is updated to respect the caller's preference for using the lockfile. The addition of a targeted e2e test is excellent for preventing future regressions. I have one minor suggestion to improve a comment in the new test file for clarity.
| # Create a lockfile with the old version locked | ||
| touch mise.lock |
There was a problem hiding this comment.
The comment on line 22 is slightly misleading. touch mise.lock creates an empty file to enable lockfile functionality, but it doesn't lock a version itself. The version gets locked by the subsequent mise install command. Consider clarifying the comment to reflect this for future readers.
# Enable lockfile functionality by creating an empty lock file
touch mise.lock
Hyperfine Performance
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.2.3 x -- echo |
15.8 ± 0.4 | 14.8 | 18.0 | 1.00 |
mise x -- echo |
16.0 ± 0.4 | 15.0 | 17.4 | 1.01 ± 0.04 |
mise env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.2.3 env |
15.8 ± 0.7 | 14.4 | 25.9 | 1.00 |
mise env |
16.6 ± 0.6 | 14.9 | 20.4 | 1.05 ± 0.06 |
mise hook-env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.2.3 hook-env |
16.3 ± 0.4 | 15.1 | 17.4 | 1.00 |
mise hook-env |
16.6 ± 0.6 | 15.2 | 22.6 | 1.02 ± 0.04 |
mise ls
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.2.3 ls |
14.7 ± 0.4 | 13.6 | 16.0 | 1.00 |
mise ls |
15.0 ± 0.4 | 13.9 | 16.4 | 1.02 ± 0.04 |
xtasks/test/perf
| Command | mise-2026.2.3 | mise | Variance |
|---|---|---|---|
| install (cached) | 84ms | 83ms | +1% |
| ls (cached) | 55ms | 56ms | -1% |
| bin-paths (cached) | 60ms | 58ms | +3% |
| task-ls (cached) | 455ms | 457ms | +0% |
### 🐛 Bug Fixes - **(env)** resolve sourced env for tool templates by @corymhall in [#7895](#7895) - **(npm)** only declare the configured package manager as a dependency by @jdx in [#7995](#7995) - **(upgrade)** respect use_locked_version when checking tracked configs by @jdx in [#7997](#7997) - ignore MISE_TOOL_VERSION in env var parsing by @jdx in [#8004](#8004) ### New Contributors - @corymhall made their first contribution in [#7895](#7895)
jdx#7997) ## Summary Fixes `mise upgrade` incorrectly keeping old versions when lockfile is enabled. - When checking which versions are needed by tracked configs during upgrade, the code was always using the lockfile to resolve versions even when `use_locked_version` was explicitly set to `false` - This caused old versions to be incorrectly kept after upgrade because the lockfile hadn't been updated yet - The debug message "Keeping X because it's still needed by a tracked config" would appear even when no tracked config actually needed the old version ## Root Cause In `tool_version_list.rs`, when resolving versions that aren't "latest", the code was overriding `use_locked_version` to `true` regardless of what the caller passed in: ```rust // Before: ResolveOptions { latest_versions: false, use_locked_version: true, // Always true, ignoring caller's setting ..opts.clone() } ``` ## Fix 1. `get_versions_needed_by_tracked_configs` now explicitly requests `use_locked_version: false` 2. `ToolVersionList::resolve` now respects the caller's `use_locked_version` setting Fixes jdx#7991 ## Test plan - [x] Added e2e test `test_lockfile_upgrade_prune` that verifies old versions are removed after upgrade with lockfile enabled - [x] Existing upgrade tests pass - [x] Existing prune tests pass - [x] Existing lockfile tests pass - [x] Unit tests pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches version resolution used by both `mise upgrade` and `mise prune`, which can change which tool versions are considered “needed” and therefore uninstalled. Scope is small and covered by a new e2e regression test, but mistakes could lead to unexpected installs/removals when lockfiles are enabled. > > **Overview** > Fixes a lockfile-enabled upgrade regression where `mise upgrade` could incorrectly keep old tool versions by resolving tracked config requirements from the *previously locked* version. > > `get_versions_needed_by_tracked_configs` now resolves tracked configs with `use_locked_version: false`, and `ToolVersionList::resolve` no longer forces `use_locked_version=true` for non-`latest` requests (it inherits the caller’s setting). > > Adds an e2e regression test (`e2e/lockfile/test_lockfile_upgrade_prune`) asserting that upgrading a prefix version updates the lockfile and prunes the old installed version. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 8c068fe. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
### 🐛 Bug Fixes - **(env)** resolve sourced env for tool templates by @corymhall in [jdx#7895](jdx#7895) - **(npm)** only declare the configured package manager as a dependency by @jdx in [jdx#7995](jdx#7995) - **(upgrade)** respect use_locked_version when checking tracked configs by @jdx in [jdx#7997](jdx#7997) - ignore MISE_TOOL_VERSION in env var parsing by @jdx in [jdx#8004](jdx#8004) ### New Contributors - @corymhall made their first contribution in [jdx#7895](jdx#7895)
Summary
Fixes
mise upgradeincorrectly keeping old versions when lockfile is enabled.use_locked_versionwas explicitly set tofalseRoot Cause
In
tool_version_list.rs, when resolving versions that aren't "latest", the code was overridinguse_locked_versiontotrueregardless of what the caller passed in:Fix
get_versions_needed_by_tracked_configsnow explicitly requestsuse_locked_version: falseToolVersionList::resolvenow respects the caller'suse_locked_versionsettingFixes #7991
Test plan
test_lockfile_upgrade_prunethat verifies old versions are removed after upgrade with lockfile enabled🤖 Generated with Claude Code
Note
Medium Risk
Touches version resolution used by both
mise upgradeandmise prune, which can change which tool versions are considered “needed” and therefore uninstalled. Scope is small and covered by a new e2e regression test, but mistakes could lead to unexpected installs/removals when lockfiles are enabled.Overview
Fixes a lockfile-enabled upgrade regression where
mise upgradecould incorrectly keep old tool versions by resolving tracked config requirements from the previously locked version.get_versions_needed_by_tracked_configsnow resolves tracked configs withuse_locked_version: false, andToolVersionList::resolveno longer forcesuse_locked_version=truefor non-latestrequests (it inherits the caller’s setting).Adds an e2e regression test (
e2e/lockfile/test_lockfile_upgrade_prune) asserting that upgrading a prefix version updates the lockfile and prunes the old installed version.Written by Cursor Bugbot for commit 8c068fe. This will update automatically on new commits. Configure here.