fix(lockfile): resolve version aliases before lockfile lookup#8194
Conversation
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 addresses a critical bug where 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 an issue where version aliases were not being resolved before checking the lockfile. The introduction of lockfile_resolve_with_prefix and its usage after alias resolution is a logical fix. The new e2e test provides good coverage for this scenario.
I've left a couple of comments regarding code duplication. These are suggestions to improve maintainability and are not critical to the functionality of this fix.
src/toolset/tool_request.rs
Outdated
| match self.source() { | ||
| ToolSource::MiseToml(path) => lockfile::get_locked_version( | ||
| config, | ||
| Some(path), | ||
| &self.ba().short, | ||
| prefix, | ||
| &request_options, | ||
| ), | ||
| _ => lockfile::get_locked_version( | ||
| config, | ||
| None, | ||
| &self.ba().short, | ||
| prefix, | ||
| &request_options, | ||
| ), | ||
| } |
There was a problem hiding this comment.
This match statement can be simplified to avoid duplicating the call to lockfile::get_locked_version. This also makes the code more DRY and easier to maintain. A similar refactoring could be applied to lockfile_resolve.
let path = match self.source() {
ToolSource::MiseToml(path) => Some(path),
_ => None,
};
lockfile::get_locked_version(
config,
path,
&self.ba().short,
prefix,
&request_options,
)
src/toolset/tool_version.rs
Outdated
| let mut tv = Self::new(request.clone(), lt.version); | ||
| tv.lock_platforms = lt.platforms; | ||
| return Ok(tv); |
There was a problem hiding this comment.
When using version aliases like `node = "lts"`, the lockfile was not
being respected because the lockfile check happened before alias
resolution. The prefix "lts" would never match a lockfile entry like
"24.13.0".starts_with("lts"). After alias resolution ("lts" → "24"),
the lockfile is now re-checked so "24.13.0".starts_with("24") matches.
Fixes #8175
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
f276b05 to
84df394
Compare
There was a problem hiding this comment.
Pull request overview
Fixes lockfile resolution when tool versions are specified via aliases (e.g., node = "lts"), by re-checking the lockfile after alias resolution so prefix matching works as intended.
Changes:
- Re-check the lockfile after resolving a version alias during tool version resolution.
- Add
ToolRequest::lockfile_resolve_with_prefixto support lockfile lookups using a custom prefix. - Add an e2e test ensuring lockfiles are respected when using custom version aliases.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/toolset/tool_version.rs |
Adds a post-alias lockfile re-check during version resolution to ensure lockfile prefix matches work after alias expansion. |
src/toolset/tool_request.rs |
Introduces a lockfile lookup helper that accepts an explicit prefix (used post-alias resolution). |
e2e/lockfile/test_lockfile_alias |
New e2e coverage validating alias → version resolution still respects lockfile-pinned versions. |
Comments suppressed due to low confidence (1)
src/toolset/tool_request.rs:301
lockfile_resolve_with_prefixduplicates therequest_options+match self.source()logic fromlockfile_resolve. Consider extracting a single private helper (e.g., taking an explicit prefix) and having both methods delegate to it to avoid future drift.
if let Some(backend) = backend::get(self.ba()) {
let matches = backend.list_installed_versions_matching(v);
if matches.iter().any(|m| m == v) {
return Ok(Some(v.to_string()));
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| && !has_linked_version(request.ba()) | ||
| && let Some(lt) = request.lockfile_resolve_with_prefix(config, &v)? | ||
| { | ||
| return Ok(Self::from_lockfile(request.clone(), lt)); |
There was a problem hiding this comment.
In this new lockfile-return path, request.clone() is unnecessary because the function returns immediately; you can move request into ToolVersion::new to avoid an extra clone/allocation.
| return Ok(Self::from_lockfile(request.clone(), lt)); | |
| return Ok(Self::from_lockfile(request, lt)); |
Hyperfine Performance
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.2.13 x -- echo |
24.5 ± 0.8 | 23.1 | 27.0 | 1.00 |
mise x -- echo |
25.3 ± 1.7 | 23.4 | 46.4 | 1.03 ± 0.08 |
mise env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.2.13 env |
25.2 ± 1.0 | 22.8 | 29.1 | 1.02 ± 0.05 |
mise env |
24.6 ± 0.9 | 22.8 | 26.8 | 1.00 |
mise hook-env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.2.13 hook-env |
26.3 ± 0.8 | 23.7 | 29.2 | 1.00 ± 0.05 |
mise hook-env |
26.2 ± 0.9 | 23.5 | 27.7 | 1.00 |
mise ls
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.2.13 ls |
23.3 ± 1.0 | 21.6 | 25.6 | 1.00 |
mise ls |
23.7 ± 1.0 | 22.1 | 26.2 | 1.02 ± 0.06 |
xtasks/test/perf
| Command | mise-2026.2.13 | mise | Variance |
|---|---|---|---|
| install (cached) | 131ms | 136ms | -3% |
| ls (cached) | 83ms | 85ms | -2% |
| bin-paths (cached) | 87ms | 89ms | -2% |
| task-ls (cached) | 849ms | 863ms | -1% |
### 🚀 Features - **(task)** stream keep-order output in real-time per task by @jdx in [#8164](#8164) ### 🐛 Bug Fixes - **(aqua)** resolve lockfile artifacts for target platform (fix discussion #7479) by @mackwic in [#8183](#8183) - **(exec)** strip shims from PATH to prevent recursive shim execution by @jdx in [#8189](#8189) - **(hook-env)** preserve PATH reordering done after activation by @jdx in [#8190](#8190) - **(lockfile)** resolve version aliases before lockfile lookup by @jdx in [#8194](#8194) - **(registry)** set helm-diff archive bin name to diff by @jean-humann in [#8173](#8173) - **(task)** improve source freshness checks with dynamic task dirs by @rooperuu in [#8169](#8169) - **(task)** resolve global tasks when running from monorepo root by @jdx in [#8192](#8192) - **(task)** prevent wildcard glob `test:*` from matching parent task `test` by @jdx in [#8165](#8165) - **(task)** resolve task_config.includes relative to config root by @jdx in [#8193](#8193) - **(upgrade)** skip untrusted tracked configs during upgrade by @jdx in [#8195](#8195) ### 🚜 Refactor - use enum for npm.pacakge_manager by @risu729 in [#8180](#8180) ### 📚 Documentation - **(plugins)** replace node/asdf-nodejs examples with vfox plugins by @jdx in [#8191](#8191) ### ⚡ Performance - call npm view only once by @risu729 in [#8181](#8181) ### New Contributors - @jean-humann made their first contribution in [#8173](#8173) - @mackwic made their first contribution in [#8183](#8183) - @rooperuu made their first contribution in [#8169](#8169) ## 📦 Aqua Registry Updates #### New Packages (2) - [`BetterDiscord/cli`](https://github.com/BetterDiscord/cli) - [`glossia.ai/cli`](https://github.com/glossia.ai/cli)
## Summary
- Fixes lockfile not being respected when using version aliases like
`node = "lts"`
- The lockfile check was happening before alias resolution, so prefix
matching `"24.13.0".starts_with("lts")` would fail
- After alias resolution (e.g., `"lts"` → `"24"`), the lockfile is now
re-checked so `"24.13.0".starts_with("24")` matches correctly
Fixes jdx#8175
## Test plan
- [x] Added `e2e/lockfile/test_lockfile_alias` — verifies lockfile is
respected with custom aliases
- [x] All existing lockfile e2e tests pass (`test_lockfile_install`,
`test_lockfile_exec`, `test_lockfile_use`, `test_lockfile_local`,
`test_lockfile_env_resolution`)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Touches core version resolution and lockfile matching paths, which can
affect which versions get installed/selected across tools; the change is
small and covered by a new e2e test but could alter behavior for
alias/prefix edge cases.
>
> **Overview**
> Fixes a bug where lockfiles were ignored when a tool version was
specified via an alias (e.g. `lts`/custom alias), by adding a second
lockfile lookup after alias resolution using the resolved version as the
prefix.
>
> Refactors lockfile resolution to support a custom prefix via
`ToolRequest::lockfile_resolve_with_prefix`, and centralizes
lockfile-to-`ToolVersion` construction. Adds an e2e test
(`e2e/lockfile/test_lockfile_alias`) to verify the requested version
remains the alias while the installed/resolved version comes from
`mise.lock`.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
84df394. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
### 🚀 Features - **(task)** stream keep-order output in real-time per task by @jdx in [jdx#8164](jdx#8164) ### 🐛 Bug Fixes - **(aqua)** resolve lockfile artifacts for target platform (fix discussion jdx#7479) by @mackwic in [jdx#8183](jdx#8183) - **(exec)** strip shims from PATH to prevent recursive shim execution by @jdx in [jdx#8189](jdx#8189) - **(hook-env)** preserve PATH reordering done after activation by @jdx in [jdx#8190](jdx#8190) - **(lockfile)** resolve version aliases before lockfile lookup by @jdx in [jdx#8194](jdx#8194) - **(registry)** set helm-diff archive bin name to diff by @jean-humann in [jdx#8173](jdx#8173) - **(task)** improve source freshness checks with dynamic task dirs by @rooperuu in [jdx#8169](jdx#8169) - **(task)** resolve global tasks when running from monorepo root by @jdx in [jdx#8192](jdx#8192) - **(task)** prevent wildcard glob `test:*` from matching parent task `test` by @jdx in [jdx#8165](jdx#8165) - **(task)** resolve task_config.includes relative to config root by @jdx in [jdx#8193](jdx#8193) - **(upgrade)** skip untrusted tracked configs during upgrade by @jdx in [jdx#8195](jdx#8195) ### 🚜 Refactor - use enum for npm.pacakge_manager by @risu729 in [jdx#8180](jdx#8180) ### 📚 Documentation - **(plugins)** replace node/asdf-nodejs examples with vfox plugins by @jdx in [jdx#8191](jdx#8191) ### ⚡ Performance - call npm view only once by @risu729 in [jdx#8181](jdx#8181) ### New Contributors - @jean-humann made their first contribution in [jdx#8173](jdx#8173) - @mackwic made their first contribution in [jdx#8183](jdx#8183) - @rooperuu made their first contribution in [jdx#8169](jdx#8169) ## 📦 Aqua Registry Updates #### New Packages (2) - [`BetterDiscord/cli`](https://github.com/BetterDiscord/cli) - [`glossia.ai/cli`](https://github.com/glossia.ai/cli)
### 🚀 Features - **(task)** stream keep-order output in real-time per task by @jdx in [jdx#8164](jdx#8164) ### 🐛 Bug Fixes - **(aqua)** resolve lockfile artifacts for target platform (fix discussion jdx#7479) by @mackwic in [jdx#8183](jdx#8183) - **(exec)** strip shims from PATH to prevent recursive shim execution by @jdx in [jdx#8189](jdx#8189) - **(hook-env)** preserve PATH reordering done after activation by @jdx in [jdx#8190](jdx#8190) - **(lockfile)** resolve version aliases before lockfile lookup by @jdx in [jdx#8194](jdx#8194) - **(registry)** set helm-diff archive bin name to diff by @jean-humann in [jdx#8173](jdx#8173) - **(task)** improve source freshness checks with dynamic task dirs by @rooperuu in [jdx#8169](jdx#8169) - **(task)** resolve global tasks when running from monorepo root by @jdx in [jdx#8192](jdx#8192) - **(task)** prevent wildcard glob `test:*` from matching parent task `test` by @jdx in [jdx#8165](jdx#8165) - **(task)** resolve task_config.includes relative to config root by @jdx in [jdx#8193](jdx#8193) - **(upgrade)** skip untrusted tracked configs during upgrade by @jdx in [jdx#8195](jdx#8195) ### 🚜 Refactor - use enum for npm.pacakge_manager by @risu729 in [jdx#8180](jdx#8180) ### 📚 Documentation - **(plugins)** replace node/asdf-nodejs examples with vfox plugins by @jdx in [jdx#8191](jdx#8191) ### ⚡ Performance - call npm view only once by @risu729 in [jdx#8181](jdx#8181) ### New Contributors - @jean-humann made their first contribution in [jdx#8173](jdx#8173) - @mackwic made their first contribution in [jdx#8183](jdx#8183) - @rooperuu made their first contribution in [jdx#8169](jdx#8169) ## 📦 Aqua Registry Updates #### New Packages (2) - [`BetterDiscord/cli`](https://github.com/BetterDiscord/cli) - [`glossia.ai/cli`](https://github.com/glossia.ai/cli)
Summary
node = "lts""24.13.0".starts_with("lts")would fail"lts"→"24"), the lockfile is now re-checked so"24.13.0".starts_with("24")matches correctlyFixes #8175
Test plan
e2e/lockfile/test_lockfile_alias— verifies lockfile is respected with custom aliasestest_lockfile_install,test_lockfile_exec,test_lockfile_use,test_lockfile_local,test_lockfile_env_resolution)🤖 Generated with Claude Code
Note
Medium Risk
Touches core version resolution and lockfile matching paths, which can affect which versions get installed/selected across tools; the change is small and covered by a new e2e test but could alter behavior for alias/prefix edge cases.
Overview
Fixes a bug where lockfiles were ignored when a tool version was specified via an alias (e.g.
lts/custom alias), by adding a second lockfile lookup after alias resolution using the resolved version as the prefix.Refactors lockfile resolution to support a custom prefix via
ToolRequest::lockfile_resolve_with_prefix, and centralizes lockfile-to-ToolVersionconstruction. Adds an e2e test (e2e/lockfile/test_lockfile_alias) to verify the requested version remains the alias while the installed/resolved version comes frommise.lock.Written by Cursor Bugbot for commit 84df394. This will update automatically on new commits. Configure here.