Skip to content

fix(install): normalize "v" prefix when matching lockfile versions#8413

Merged
jdx merged 2 commits intomainfrom
fix/lockfile-v-prefix-mismatch
Mar 2, 2026
Merged

fix(install): normalize "v" prefix when matching lockfile versions#8413
jdx merged 2 commits intomainfrom
fix/lockfile-v-prefix-mismatch

Conversation

@jdx
Copy link
Copy Markdown
Owner

@jdx jdx commented Mar 2, 2026

Summary

  • When mise.toml specifies a version with a "v" prefix (e.g., setup-envtest = "v0.23.1") but the lockfile stores the resolved version without it (version = "0.23.1"), --locked mode would fail with "is not in the lockfile"
  • Strip the "v"/"V" prefix from the version before comparing against lockfile entries so both forms match

Fixes #8411

Test plan

  • Added e2e test test_lockfile_v_prefix that verifies --locked --dry-run succeeds when mise.toml has "v" prefix and lockfile doesn't
  • Verified the test fails without the fix
  • Existing lockfile e2e tests (test_lockfile_locked_mode, test_lockfile_install) still pass

🤖 Generated with Claude Code


Note

Low Risk
Low risk: small, localized change to lockfile version matching that only relaxes comparisons by ignoring a leading v/V, plus an e2e test to cover the regression.

Overview
get_locked_version now normalizes tool version prefixes by stripping a leading v/V from both the requested version and lockfile entries before doing the starts_with match, preventing --locked failures when mise.toml uses v1.2.3 but mise.lock stores 1.2.3.

Adds an e2e regression test (test_lockfile_v_prefix) that writes a mise.toml with jq = "v1.7.1" and a lockfile with version = "1.7.1", asserting mise install --locked --dry-run succeeds.

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

When mise.toml specifies a version with a "v" prefix (e.g., "v0.23.1")
but the lockfile stores the resolved version without it (e.g., "0.23.1"),
--locked mode would fail with "is not in the lockfile". Strip the "v"/"V"
prefix before comparing so both forms match.

Fixes #8411

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, 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 enhances the robustness of mise install --locked by improving how versions are matched against the lockfile. Previously, a mismatch in "v" prefixes between the mise.toml configuration and the lockfile could lead to installation failures. The changes introduce a normalization step to handle these prefix variations, ensuring that tools are correctly identified and installed even when version strings differ only by a "v" prefix.

Highlights

  • Lockfile Version Matching: Resolved an issue where mise install --locked would fail if mise.toml specified a version with a "v" prefix (e.g., "v1.7.1") but the lockfile stored the version without it ("1.7.1").
  • Version Normalization: Implemented logic to strip "v" or "V" prefixes from versions when comparing against lockfile entries, ensuring consistent matching regardless of prefix presence.
  • Test Coverage: Added a new end-to-end test (test_lockfile_v_prefix) to specifically verify the fix and confirmed existing lockfile tests remain passing.
Changelog
  • e2e/lockfile/test_lockfile_v_prefix
    • Added a new end-to-end test to verify lockfile matching with 'v' prefixes.
  • src/lockfile.rs
    • Modified version matching logic in get_locked_version to normalize prefixes.
    • Ensured versions with 'v' or 'V' prefixes in mise.toml correctly match lockfile entries without them.
Activity
  • Added a new e2e test test_lockfile_v_prefix to validate the fix.
  • Verified that the new test failed before applying the fix, confirming the issue.
  • Confirmed that existing lockfile e2e tests (test_lockfile_locked_mode, test_lockfile_install) continue to pass.
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request addresses an issue where versions with a 'v' prefix in mise.toml failed to match versions without it in the lockfile. The fix involves normalizing the version prefix before comparison, which is a good approach. The new end-to-end test effectively validates this scenario. I've identified a potential bug in a corner case of the implementation and suggested a more robust solution to ensure all prefix combinations are handled correctly.

src/lockfile.rs Outdated
Comment on lines +1136 to +1142
let norm_prefix = prefix
.strip_prefix('v')
.or(prefix.strip_prefix('V'))
.unwrap_or(prefix);
let version_matches = prefix == "latest"
|| v.version.starts_with(prefix)
|| v.version.starts_with(norm_prefix);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

The current logic for matching versions is a good improvement. However, it has a potential bug where it fails to match if the lockfile version has a v prefix but the requested version (prefix) does not (e.g., prefix is "1.0.0" and v.version is "v1.0.0").

A more robust approach is to normalize both the prefix and v.version by stripping any 'v'/'V' prefix before comparison. This ensures that all combinations of prefixes are handled correctly and simplifies the matching logic.

Suggested change
let norm_prefix = prefix
.strip_prefix('v')
.or(prefix.strip_prefix('V'))
.unwrap_or(prefix);
let version_matches = prefix == "latest"
|| v.version.starts_with(prefix)
|| v.version.starts_with(norm_prefix);
let norm_prefix = prefix
.strip_prefix('v')
.or(prefix.strip_prefix('V'))
.unwrap_or(prefix);
let norm_v_version = v.version.strip_prefix('v')
.or(v.version.strip_prefix('V'))
.unwrap_or(&v.version);
let version_matches = prefix == "latest" || norm_v_version.starts_with(norm_prefix);

Also strip "v"/"V" prefix from the lockfile version, not just the
requested prefix. This handles the reverse case where the lockfile
has a "v" prefix but the request does not.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 2, 2026

Greptile Summary

This PR fixes a bug where --locked mode would fail when mise.toml specifies a version with a "v" prefix (e.g., jq = "v1.7.1") but the lockfile stores the version without it (version = "1.7.1"). The fix normalizes the version prefix by stripping "v"/"V" before matching against lockfile entries.

Changes:

  • Modified get_locked_version() in src/lockfile.rs to strip "v"/"V" prefix from the user-specified version before comparing with lockfile entries
  • Added comprehensive e2e test test_lockfile_v_prefix to verify the fix works correctly

The implementation correctly handles the reported issue and maintains backward compatibility with existing version matching logic.

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The change is minimal, well-tested, and correctly addresses the reported bug. The fix only affects version matching logic in locked mode and adds a new OR condition that handles the "v" prefix case without breaking existing behavior. The e2e test provides good coverage of the fix.
  • No files require special attention

Important Files Changed

Filename Overview
src/lockfile.rs Adds version prefix normalization to fix "v" prefix matching in locked mode
e2e/lockfile/test_lockfile_v_prefix New test verifying lockfile matching with "v" prefix in mise.toml

Last reviewed commit: cbaaa8e

@jdx jdx enabled auto-merge (squash) March 2, 2026 02:55
@jdx jdx merged commit 6bc524a into main Mar 2, 2026
35 checks passed
@jdx jdx deleted the fix/lockfile-v-prefix-mismatch branch March 2, 2026 03:07
@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 2, 2026

Hyperfine Performance

mise x -- echo

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.2.24 x -- echo 29.2 ± 0.7 27.8 35.2 1.18 ± 0.05
mise x -- echo 24.8 ± 0.9 23.5 33.0 1.00
✅ Performance improvement for x -- echo is 18%

mise env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.2.24 env 29.4 ± 1.2 27.2 38.2 1.22 ± 0.06
mise env 24.2 ± 0.7 22.9 27.0 1.00
✅ Performance improvement for env is 22%

mise hook-env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.2.24 hook-env 30.6 ± 1.2 28.6 37.3 1.20 ± 0.06
mise hook-env 25.4 ± 0.9 23.8 30.6 1.00
✅ Performance improvement for hook-env is 20%

mise ls

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.2.24 ls 24.1 ± 0.8 22.6 29.1 1.04 ± 0.05
mise ls 23.1 ± 1.0 21.5 28.8 1.00

xtasks/test/perf

Command mise-2026.2.24 mise Variance
install (cached) 169ms 156ms +8%
ls (cached) 92ms 84ms +9%
bin-paths (cached) 100ms ✅ 89ms +12%
task-ls (cached) 889ms 857ms +3%

✅ Performance improvement: bin-paths cached is 12%

jdx pushed a commit that referenced this pull request Mar 2, 2026
### 🚀 Features

- **(hooks)** add task references to hooks and watch_files by @jdx in
[#8400](#8400)
- **(prepare)** add git-submodule built-in provider by @jdx in
[#8407](#8407)
- **(prepare)** add human-readable stale reasons to prepare output by
@jdx in [#8408](#8408)
- **(prepare)** add dependency ordering to prepare steps by @jdx in
[#8401](#8401)
- **(prepare)** add --explain flag for provider diagnostics by @jdx in
[#8409](#8409)
- **(prepare)** add per-provider timeout support by @jdx in
[#8405](#8405)
- **(prepare)** add blake3 content-hash freshness checking by @jdx in
[#8404](#8404)
- **(tasks)** monorepo vars and per-task vars by @halms in
[#8248](#8248)

### 🐛 Bug Fixes

- **(aqua)** restore bin_paths disk cache with fresh_file invalidation
by @jdx in [#8398](#8398)
- **(idiomatic)** use generic parser for idiomatic files by @risu729 in
[#8171](#8171)
- **(install)** apply precompiled options to all platforms in lockfile
by @jdx in [#8396](#8396)
- **(install)** normalize "v" prefix when matching lockfile versions by
@jdx in [#8413](#8413)
- **(prepare)** improve git submodule parser and fix check_staleness
error handling by @jdx in [#8412](#8412)
- **(python)** respect precompiled settings in lock file generation by
@jdx in [#8399](#8399)
- **(python)** clarify uv_venv_auto docs + prevent uv shim recursion in
venv creation by @halms in
[#8402](#8402)
- **(task)** remove deprecated `# mise` task header syntax by @jdx in
[#8403](#8403)
- **(vfox)** avoid eager metadata loading during config file detection
by @jdx in [#8397](#8397)
- clarify GitHub attestations to be artifact ones by @scop in
[#8394](#8394)
- ignore comments in idiomatic version files by @iloveitaly in
[#7682](#7682)

### 🚜 Refactor

- unify archive detection by @risu729 in
[#8137](#8137)

### 📚 Documentation

- remove duplicated docs for npm.package_manager by @risu729 in
[#8414](#8414)
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.

1 participant