Skip to content

fix(lockfile): error on contradictory locked=true + lockfile=false config#8329

Merged
jdx merged 2 commits intomainfrom
fix/locked-implies-lockfile
Feb 24, 2026
Merged

fix(lockfile): error on contradictory locked=true + lockfile=false config#8329
jdx merged 2 commits intomainfrom
fix/locked-implies-lockfile

Conversation

@jdx
Copy link
Owner

@jdx jdx commented Feb 24, 2026

Summary

  • Makes the lockfile setting nullable (Option<bool>) with three states:
    • Some(true) / true = lockfile enabled (read + write)
    • Some(false) / false = lockfile explicitly disabled — errors if locked=true
    • None (unset, default) = same as true, no conflict with locked
  • Adds lockfile_enabled() helper as the single source of truth for whether lockfiles should be active
  • Errors early with a clear message when locked=true and lockfile=false are both set (contradictory config)

Closes #8305

Test plan

  • mise run build succeeds
  • mise run lint-fix passes
  • mise run test:e2e lockfile/test_lockfile_locked_mode — 6 tests covering:
    • --locked fails without lockfile URL
    • --locked --dry-run also validates
    • --locked --dry-run succeeds with lockfile URL
    • MISE_LOCKFILE=0 + --locked errors (env var contradiction)
    • locked=true + lockfile=false in config errors (config contradiction)
    • locked=true with lockfile unset works fine
  • mise run test:e2e lockfile/test_lockfile_install lockfile/test_lockfile_auto_lock lockfile/test_lockfile_exec — existing lockfile tests still pass

🤖 Generated with Claude Code


Note

Low Risk
Small, well-scoped behavior change around settings resolution and lockfile gating; main risk is unintended changes for users relying on previous lockfile default semantics.

Overview
Adds a tri-state lockfile setting (unset vs true vs false) and centralizes the effective behavior in Settings::lockfile_enabled() so lockfile reads/writes/checksum generation treat “unset” as enabled.

Introduces an early install-time validation that fails with a clear hint when locked mode (CLI or settings) is used while lockfile = false, and updates docs/schema plus e2e coverage for env/config contradictions and the “unset but locked” case.

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

…setting is disabled

When `locked = true` but `lockfile = false` (e.g., via MISE_LOCKFILE=false env var),
lockfile resolution was completely skipped, causing all tools to fail with
"No lockfile URL found" errors. This is because `locked` mode requires lockfile
URLs but the lockfile reading was gated solely on the `lockfile` setting.

Now `locked = true` implies lockfile reading is enabled, so tools can still
resolve versions and platform URLs from the lockfile. The lockfile *write*
guards are unchanged — locked mode still prevents lockfile modifications.

Fixes #8305

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings February 24, 2026 12:25
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @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 mise install in locked mode would fail if the lockfile setting was disabled, even when a valid lockfile was present. The fix ensures that locked mode implicitly enables lockfile reading, allowing tools to be installed correctly while still preventing unintended lockfile modifications. This improves the robustness of mise's lockfile handling, especially in environments with strict configuration overrides.

Highlights

  • Lockfile Read Logic: Modified get_locked_version() and get_locked_backend() functions to ensure lockfile reading is enabled when locked = true, even if the lockfile setting is otherwise disabled.
  • locked and lockfile Settings Interaction: Resolved an issue where mise install would fail in locked mode if the lockfile setting was explicitly disabled (e.g., via MISE_LOCKFILE=false), preventing lockfile resolution.
  • Test Coverage: Added new end-to-end tests to specifically cover scenarios where locked = true coexists with lockfile = false (both via environment variable and mise.toml settings).
Changelog
  • e2e/lockfile/test_lockfile_locked_mode
    • Added a new test case (Test 4) to verify that mise install --locked --dry-run succeeds when MISE_LOCKFILE=0 is set and the lockfile contains platform URLs.
    • Added another new test case (Test 5) to confirm that mise install --dry-run works when locked = true and lockfile = false are configured in mise.toml.
  • src/lockfile.rs
    • Updated the conditional check in get_locked_version to allow lockfile reading if settings.locked is true, regardless of settings.lockfile.
    • Updated the conditional check in get_locked_backend to allow lockfile reading if settings.locked is true, regardless of settings.lockfile.
Activity
  • Existing test_lockfile_locked_mode tests passed.
  • New Test 4 was added to verify MISE_LOCKFILE=0 with locked=true reads the lockfile.
  • New Test 5 was added to verify locked=true and lockfile=false in mise.toml reads the lockfile.
  • The full lockfile e2e suite passed.
  • mise run lint-fix passed.
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
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

The pull request effectively addresses the issue where mise install would fail in locked mode when the lockfile setting was disabled. The changes correctly modify get_locked_version() and get_locked_backend() to consider the locked setting, ensuring lockfile reads are enabled when locked = true. The new end-to-end tests adequately cover the fixed scenarios, confirming the intended behavior. The code changes are minimal and targeted, reducing the risk of unintended side effects.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a bug where users with locked = true and lockfile = false (e.g., via MISE_LOCKFILE=false env override) would encounter "No lockfile URL found" errors during mise install, even when the lockfile contained all necessary platform URLs. The root cause was that lockfile reading functions were gated solely on the lockfile setting, ignoring the locked setting. The fix establishes that locked = true implies lockfile reading is enabled, while keeping lockfile write guards unchanged.

Changes:

  • Modified get_locked_version() and get_locked_backend() to read lockfiles when locked = true, regardless of lockfile setting
  • Added comprehensive tests verifying the fix works with both environment variable overrides and config file settings

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/lockfile.rs Changed lockfile read guards from !settings.lockfile to !settings.lockfile && !settings.locked in get_locked_version() and get_locked_backend()
e2e/lockfile/test_lockfile_locked_mode Added Test 4 (env var override) and Test 5 (config file settings) to verify locked mode reads lockfiles even when lockfile = false

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

@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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

@github-actions
Copy link

github-actions bot commented Feb 24, 2026

Hyperfine Performance

mise x -- echo

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.2.19 x -- echo 23.6 ± 0.7 22.9 34.2 1.00
mise x -- echo 24.3 ± 0.7 23.5 35.7 1.03 ± 0.04

mise env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.2.19 env 22.1 ± 0.6 21.5 29.4 1.00
mise env 23.3 ± 0.8 22.3 33.2 1.05 ± 0.04

mise hook-env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.2.19 hook-env 23.1 ± 0.5 22.0 27.8 1.00
mise hook-env 24.5 ± 0.6 23.1 27.3 1.06 ± 0.04

mise ls

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.2.19 ls 20.3 ± 0.3 19.7 21.4 1.00
mise ls 21.6 ± 0.5 20.7 24.0 1.06 ± 0.03

xtasks/test/perf

Command mise-2026.2.19 mise Variance
install (cached) 124ms ⚠️ 150ms -17%
ls (cached) 77ms 83ms -7%
bin-paths (cached) 80ms 87ms -8%
task-ls (cached) 799ms 810ms -1%

⚠️ Warning: install cached performance variance is -17%

@jdx jdx changed the title fix(lockfile): allow locked mode to read lockfile even when lockfile setting is disabled fix(lockfile): error on contradictory locked=true + lockfile=false config Feb 24, 2026
…nfig

Make lockfile setting nullable (Option<bool>) with three states:
- Some(true): lockfile enabled (read + write)
- Some(false): lockfile explicitly disabled, errors if locked=true
- None (default): same as true, no conflict with locked mode

Add lockfile_enabled() helper as single source of truth. Error early
with a clear message when locked and lockfile=false are both set.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jdx jdx merged commit 41cab17 into main Feb 24, 2026
36 checks passed
@jdx jdx deleted the fix/locked-implies-lockfile branch February 24, 2026 14:31
mise-en-dev added a commit that referenced this pull request Feb 25, 2026
### 🚀 Features

- **(conda)** replace custom backend with rattler crates by @jdx in
[#8325](#8325)
- **(task)** enforce per-task timeout configuration by @tvararu in
[#8250](#8250)
- **(vsix)** added vsix archives to http backend by @sosumappu in
[#8306](#8306)
- add core dotnet plugin for .NET SDK management by @jdx in
[#8326](#8326)

### 🐛 Bug Fixes

- **(conda)** preserve conda_packages on locked install and fix temp
file race by @jdx in [#8335](#8335)
- **(conda)** deduplicate repodata records to fix solver error on Linux
by @jdx in [#8337](#8337)
- **(env)** include watch_files in fast-path early exit check by @jdx in
[#8317](#8317)
- **(env)** clear fish completions when setting/unsetting shell aliases
by @jdx in [#8324](#8324)
- **(lockfile)** prevent lockfile writes when --locked is set by @jdx in
[#8308](#8308)
- **(lockfile)** prune orphan tool entries on mise lock by @mackwic in
[#8265](#8265)
- **(lockfile)** error on contradictory locked=true + lockfile=false
config by @jdx in [#8329](#8329)
- **(regal)** Update package location by @charlieegan3 in
[#8315](#8315)
- **(release)** strip markdown heading prefix from communique release
title by @jdx in [#8303](#8303)
- **(schema)** enforce additionalProperties constraint for env by
@adamliang0 in [#8328](#8328)

### 📚 Documentation

- Remove incorrect oh-my-zsh plugin ordering comment by @bvosk in
[#8323](#8323)
- require AI disclosure on GitHub comments by @jdx in
[#8330](#8330)

### 📦 Registry

- add `oxfmt` by @taoufik07 in
[#8316](#8316)

### New Contributors

- @adamliang0 made their first contribution in
[#8328](#8328)
- @tvararu made their first contribution in
[#8250](#8250)
- @bvosk made their first contribution in
[#8323](#8323)
- @taoufik07 made their first contribution in
[#8316](#8316)
- @charlieegan3 made their first contribution in
[#8315](#8315)
- @sosumappu made their first contribution in
[#8306](#8306)

## 📦 Aqua Registry Updates

#### New Packages (3)

- [`Tyrrrz/FFmpegBin`](https://github.com/Tyrrrz/FFmpegBin)
- [`elixir-lang/expert`](https://github.com/elixir-lang/expert)
- [`erikjuhani/basalt`](https://github.com/erikjuhani/basalt)

#### Updated Packages (5)

- [`caarlos0/fork-cleaner`](https://github.com/caarlos0/fork-cleaner)
-
[`firecow/gitlab-ci-local`](https://github.com/firecow/gitlab-ci-local)
- [`jackchuka/mdschema`](https://github.com/jackchuka/mdschema)
-
[`kunobi-ninja/kunobi-releases`](https://github.com/kunobi-ninja/kunobi-releases)
- [`peco/peco`](https://github.com/peco/peco)
risu729 pushed a commit to risu729/mise that referenced this pull request Feb 27, 2026
risu729 pushed a commit to risu729/mise that referenced this pull request Feb 27, 2026
### 🚀 Features

- **(conda)** replace custom backend with rattler crates by @jdx in
[jdx#8325](jdx#8325)
- **(task)** enforce per-task timeout configuration by @tvararu in
[jdx#8250](jdx#8250)
- **(vsix)** added vsix archives to http backend by @sosumappu in
[jdx#8306](jdx#8306)
- add core dotnet plugin for .NET SDK management by @jdx in
[jdx#8326](jdx#8326)

### 🐛 Bug Fixes

- **(conda)** preserve conda_packages on locked install and fix temp
file race by @jdx in [jdx#8335](jdx#8335)
- **(conda)** deduplicate repodata records to fix solver error on Linux
by @jdx in [jdx#8337](jdx#8337)
- **(env)** include watch_files in fast-path early exit check by @jdx in
[jdx#8317](jdx#8317)
- **(env)** clear fish completions when setting/unsetting shell aliases
by @jdx in [jdx#8324](jdx#8324)
- **(lockfile)** prevent lockfile writes when --locked is set by @jdx in
[jdx#8308](jdx#8308)
- **(lockfile)** prune orphan tool entries on mise lock by @mackwic in
[jdx#8265](jdx#8265)
- **(lockfile)** error on contradictory locked=true + lockfile=false
config by @jdx in [jdx#8329](jdx#8329)
- **(regal)** Update package location by @charlieegan3 in
[jdx#8315](jdx#8315)
- **(release)** strip markdown heading prefix from communique release
title by @jdx in [jdx#8303](jdx#8303)
- **(schema)** enforce additionalProperties constraint for env by
@adamliang0 in [jdx#8328](jdx#8328)

### 📚 Documentation

- Remove incorrect oh-my-zsh plugin ordering comment by @bvosk in
[jdx#8323](jdx#8323)
- require AI disclosure on GitHub comments by @jdx in
[jdx#8330](jdx#8330)

### 📦 Registry

- add `oxfmt` by @taoufik07 in
[jdx#8316](jdx#8316)

### New Contributors

- @adamliang0 made their first contribution in
[jdx#8328](jdx#8328)
- @tvararu made their first contribution in
[jdx#8250](jdx#8250)
- @bvosk made their first contribution in
[jdx#8323](jdx#8323)
- @taoufik07 made their first contribution in
[jdx#8316](jdx#8316)
- @charlieegan3 made their first contribution in
[jdx#8315](jdx#8315)
- @sosumappu made their first contribution in
[jdx#8306](jdx#8306)

## 📦 Aqua Registry Updates

#### New Packages (3)

- [`Tyrrrz/FFmpegBin`](https://github.com/Tyrrrz/FFmpegBin)
- [`elixir-lang/expert`](https://github.com/elixir-lang/expert)
- [`erikjuhani/basalt`](https://github.com/erikjuhani/basalt)

#### Updated Packages (5)

- [`caarlos0/fork-cleaner`](https://github.com/caarlos0/fork-cleaner)
-
[`firecow/gitlab-ci-local`](https://github.com/firecow/gitlab-ci-local)
- [`jackchuka/mdschema`](https://github.com/jackchuka/mdschema)
-
[`kunobi-ninja/kunobi-releases`](https://github.com/kunobi-ninja/kunobi-releases)
- [`peco/peco`](https://github.com/peco/peco)
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.

2 participants