Skip to content

fix(use): write to config.toml instead of config.local.toml#8240

Merged
jdx merged 1 commit intomainfrom
docs/version-spec-syntax
Feb 18, 2026
Merged

fix(use): write to config.toml instead of config.local.toml#8240
jdx merged 1 commit intomainfrom
docs/version-spec-syntax

Conversation

@jdx
Copy link
Owner

@jdx jdx commented Feb 18, 2026

Summary

  • When both config.toml and config.local.toml exist, mise use (and mise use -g) was incorrectly writing to config.local.toml instead of config.toml.
  • Added an is_conf_d_file() helper to detect conf.d files and updated first_config_file() to skip them.
  • Updated global_config_path() to use first_config_file() instead of .last() so it always prefers config.toml over config.local.toml.

Fixes: #8236

Changes Made

  • src/config/mod.rs: Added is_conf_d_file() helper; updated first_config_file() to skip conf.d files; changed global_config_path() to call first_config_file() instead of .last().
  • e2e/cli/test_use: Added two new test cases verifying mise use and mise use -g write to config.toml when config.local.toml also exists.

Testing

  • All pre-commit lint hooks pass (cargo-check, shellcheck, shfmt, prettier, taplo).
  • Two new e2e test cases added in e2e/cli/test_use covering both local and global scenarios.

Related


Note

Low Risk
Small, targeted change to config-file write target selection with added e2e tests; low likelihood of regressions beyond which config file gets updated.

Overview
Ensures mise use and mise use -g write updates to the non-local TOML config (config.toml) instead of config.local.toml when both files exist.

This adjusts config-file selection logic to skip .config/mise/conf.d/*.toml entries and uses the shared first_config_file() selection for global_config_path(). Adds e2e coverage for both local .config/mise/config.toml and global ~/.config/mise/config.toml precedence over their .local counterparts.

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

When both config.toml and config.local.toml exist, `mise use` was
incorrectly writing to config.local.toml. Added is_conf_d_file() helper
and updated first_config_file() to skip conf.d files, then updated
global_config_path() to use first_config_file() instead of .last() so
it selects config.toml over config.local.toml.

Fixes: #8236

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings February 18, 2026 13:38
@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 resolves an issue where the mise use command was incorrectly writing configuration changes to config.local.toml even when a config.toml file existed. The changes ensure that both local and global mise use operations consistently target the primary config.toml for updates, leading to more predictable and correct configuration management.

Highlights

  • Configuration File Preference: The mise use and mise use -g commands now correctly prioritize writing to config.toml over config.local.toml when both files are present.
  • Helper Function Added: Introduced an is_conf_d_file() helper function to identify files located within a conf.d directory.
  • Config File Selection Logic: The first_config_file() function was updated to skip conf.d files, ensuring that configuration files within these directories are not inadvertently selected as primary config files.
  • Global Config Path Resolution: The global_config_path() function now utilizes first_config_file() to consistently select config.toml as the preferred global configuration file.
  • New End-to-End Tests: Added two new end-to-end test cases to validate the corrected behavior of mise use for both local and global configuration updates.
Changelog
  • e2e/cli/test_use
    • Added a test case to verify mise use writes to config.toml when config.local.toml exists.
    • Added a test case to verify mise use -g writes to config.toml when config.local.toml exists.
  • src/config/mod.rs
    • Added is_conf_d_file() helper function.
    • Updated first_config_file() to filter out conf.d files.
    • Modified global_config_path() to use first_config_file() for selecting the global config path.
Activity
  • All pre-commit lint hooks passed.
  • Two new end-to-end test cases were added to cover local and global mise use scenarios.
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

This pull request addresses an issue where mise use and mise use -g would incorrectly write to config.local.toml instead of config.toml when both files exist.

The changes include:

  • A new helper function is_conf_d_file to identify configuration files within conf.d directories.
  • An update to first_config_file to correctly ignore these conf.d files.
  • A modification to global_config_path to use first_config_file instead of .last(), ensuring it prefers config.toml over config.local.toml.

The fix appears to be correct and well-implemented. The logic is sound, and the new e2e tests in e2e/cli/test_use effectively verify the corrected behavior for both local and global configurations. The code quality is good, and I have no further suggestions for improvement.

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 mise use and mise use -g were incorrectly writing to config.local.toml when both config.toml and config.local.toml existed. Since .local.toml files have higher precedence and are meant for user-local overrides, write operations should target the lower-precedence config.toml file instead.

Changes:

  • Added is_conf_d_file() helper to identify conf.d configuration fragments
  • Updated first_config_file() to skip conf.d files in addition to .tool-versions files
  • Changed global_config_path() to use first_config_file() instead of .last() to select the appropriate config file for writes
  • Added comprehensive e2e tests verifying the fix for both local and global use cases

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/config/mod.rs Core fix: added conf.d detection and updated config file selection logic to prefer config.toml over config.local.toml for write operations
e2e/cli/test_use Added test cases verifying mise use writes to config.toml when config.local.toml also exists (both local and global scenarios)

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

.iter()
.find(|p| !is_tool_versions_file(p))
.find(|p| !is_tool_versions_file(p) && !is_conf_d_file(p))
.or_else(|| files.first())
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

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

The fallback logic .or_else(|| files.first()) may incorrectly return a conf.d file if only conf.d files exist. conf.d files are meant to be read-only configuration snippets and should never be written to.

Suggested fix: Change the fallback to .or_else(|| files.iter().find(|p| is_tool_versions_file(p))) to fall back only to .tool-versions files, not conf.d files. This way, if only conf.d files exist, the function returns None, allowing the caller's unwrap_or_else to create a proper config.toml file.

Suggested change
.or_else(|| files.first())
.or_else(|| files.iter().find(|p| is_tool_versions_file(p)))

Copilot uses AI. Check for mistakes.
@jdx jdx enabled auto-merge (squash) February 18, 2026 13:49
@jdx jdx merged commit b256ee3 into main Feb 18, 2026
43 checks passed
@jdx jdx deleted the docs/version-spec-syntax branch February 18, 2026 13:51
@github-actions
Copy link

Hyperfine Performance

mise x -- echo

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.2.16 x -- echo 23.8 ± 0.5 23.0 27.6 1.00
mise x -- echo 24.0 ± 0.6 23.0 28.8 1.01 ± 0.03

mise env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.2.16 env 23.4 ± 0.8 22.4 29.1 1.00 ± 0.04
mise env 23.4 ± 0.5 22.5 25.5 1.00

mise hook-env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.2.16 hook-env 23.9 ± 0.5 23.2 25.9 1.00
mise hook-env 24.0 ± 0.5 23.4 25.8 1.00 ± 0.03

mise ls

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.2.16 ls 21.4 ± 0.5 20.5 23.7 1.00
mise ls 21.5 ± 0.5 20.7 23.4 1.01 ± 0.03

xtasks/test/perf

Command mise-2026.2.16 mise Variance
install (cached) 132ms 132ms +0%
ls (cached) 81ms 81ms +0%
bin-paths (cached) 85ms 85ms +0%
task-ls (cached) 811ms 813ms +0%

mise-en-dev added a commit that referenced this pull request Feb 19, 2026
### 🐛 Bug Fixes

- **(install)** use backend bin paths for per-tool postinstall hooks by
@jdx in [#8234](#8234)
- **(use)** write to config.toml instead of config.local.toml by @jdx in
[#8240](#8240)
- default legacy .mise.backend installs to non-explicit by @jean-humann
in [#8245](#8245)

### 🚜 Refactor

- **(config)** consolidate flat task_* settings into nested task.* by
@jdx in [#8239](#8239)
@german-quantica
Copy link

Thank you!! Finally.

netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Feb 22, 2026
## [2026.2.18](https://github.com/jdx/mise/compare/v2026.2.17..v2026.2.18) - 2026-02-21

### 🚀 Features

- **(install)** auto-lock all platforms after tool installation by @jdx in [#8277](jdx/mise#8277)

### 🐛 Bug Fixes

- **(config)** respect --yes flag for config trust prompts by @jdx in [#8288](jdx/mise#8288)
- **(exec)** strip shims from PATH on Unix to prevent infinite recursion by @jdx in [#8276](jdx/mise#8276)
- **(install)** validate --locked before --dry-run short-circuit by @altendky in [#8290](jdx/mise#8290)
- **(release)** refresh PATH after mise up in release-plz by @jdx in [#8292](jdx/mise#8292)
- **(schema)** replace unevaluatedProperties with additionalProperties by @jdx in [#8285](jdx/mise#8285)
- **(task)** avoid duplicated stderr on task failure in replacing mode by @jdx in [#8275](jdx/mise#8275)
- **(task)** use process groups to kill child process trees on Unix by @jdx in [#8279](jdx/mise#8279)
- **(task)** run depends_post tasks even when parent task fails by @jdx in [#8274](jdx/mise#8274)
- **(task)** suggest similar commands when mistyping a CLI subcommand by @jdx in [#8286](jdx/mise#8286)
- **(task)** execute monorepo subdirectory prepare steps from root by @jdx in [#8291](jdx/mise#8291)
- **(upgrade)** don't force-reinstall already installed versions by @jdx in [#8282](jdx/mise#8282)
- **(watch)** restore terminal state after watchexec exits by @jdx in [#8273](jdx/mise#8273)

### 📚 Documentation

- clarify that MISE_CEILING_PATHS excludes the ceiling directory itself by @jdx in [#8283](jdx/mise#8283)

### Chore

- replace gen-release-notes script with communique by @jdx in [#8289](jdx/mise#8289)

### New Contributors

- @altendky made their first contribution in [#8290](jdx/mise#8290)

### 📦 Aqua Registry Updates

#### New Packages (4)

- [`Skarlso/crd-to-sample-yaml`](https://github.com/Skarlso/crd-to-sample-yaml)
- [`kunobi-ninja/kunobi-releases`](https://github.com/kunobi-ninja/kunobi-releases)
- [`swanysimon/markdownlint-rs`](https://github.com/swanysimon/markdownlint-rs)
- [`tmux/tmux-builds`](https://github.com/tmux/tmux-builds)

#### Updated Packages (2)

- [`firecow/gitlab-ci-local`](https://github.com/firecow/gitlab-ci-local)
- [`k1LoW/runn`](https://github.com/k1LoW/runn)

## [2026.2.17](https://github.com/jdx/mise/compare/v2026.2.16..v2026.2.17) - 2026-02-19

### 🚀 Features

- **(prepare)** update mtime of outputs after command is run by @halms in [#8243](jdx/mise#8243)

### 🐛 Bug Fixes

- **(install)** use backend bin paths for per-tool postinstall hooks by @jdx in [#8234](jdx/mise#8234)
- **(use)** write to config.toml instead of config.local.toml by @jdx in [#8240](jdx/mise#8240)
- default legacy .mise.backend installs to non-explicit by @jean-humann in [#8245](jdx/mise#8245)

### 🚜 Refactor

- **(config)** consolidate flat task_* settings into nested task.* by @jdx in [#8239](jdx/mise#8239)

### Chore

- **(prepare)** refactor common code into ProviderBase by @halms in [#8246](jdx/mise#8246)

### 📦 Aqua Registry Updates

#### Updated Packages (1)

- [`namespacelabs/foundation/nsc`](https://github.com/namespacelabs/foundation/nsc)
risu729 pushed a commit to risu729/mise that referenced this pull request Feb 27, 2026
## Summary

- When both `config.toml` and `config.local.toml` exist, `mise use` (and
`mise use -g`) was incorrectly writing to `config.local.toml` instead of
`config.toml`.
- Added an `is_conf_d_file()` helper to detect conf.d files and updated
`first_config_file()` to skip them.
- Updated `global_config_path()` to use `first_config_file()` instead of
`.last()` so it always prefers `config.toml` over `config.local.toml`.

Fixes: jdx#8236

## Changes Made

- `src/config/mod.rs`: Added `is_conf_d_file()` helper; updated
`first_config_file()` to skip conf.d files; changed
`global_config_path()` to call `first_config_file()` instead of
`.last()`.
- `e2e/cli/test_use`: Added two new test cases verifying `mise use` and
`mise use -g` write to `config.toml` when `config.local.toml` also
exists.

## Testing

- All pre-commit lint hooks pass (cargo-check, shellcheck, shfmt,
prettier, taplo).
- Two new e2e test cases added in `e2e/cli/test_use` covering both local
and global scenarios.

## Related

- Discussion: jdx#8236

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Small, targeted change to config-file write target selection with
added e2e tests; low likelihood of regressions beyond which config file
gets updated.
> 
> **Overview**
> Ensures `mise use` and `mise use -g` write updates to the non-local
TOML config (`config.toml`) instead of `config.local.toml` when both
files exist.
> 
> This adjusts config-file selection logic to skip
`.config/mise/conf.d/*.toml` entries and uses the shared
`first_config_file()` selection for `global_config_path()`. Adds e2e
coverage for both local `.config/mise/config.toml` and global
`~/.config/mise/config.toml` precedence over their `.local`
counterparts.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b9cb182. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
risu729 pushed a commit to risu729/mise that referenced this pull request Feb 27, 2026
### 🐛 Bug Fixes

- **(install)** use backend bin paths for per-tool postinstall hooks by
@jdx in [jdx#8234](jdx#8234)
- **(use)** write to config.toml instead of config.local.toml by @jdx in
[jdx#8240](jdx#8240)
- default legacy .mise.backend installs to non-explicit by @jean-humann
in [jdx#8245](jdx#8245)

### 🚜 Refactor

- **(config)** consolidate flat task_* settings into nested task.* by
@jdx in [jdx#8239](jdx#8239)
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