fix(install): skip tools=true env directives during backend installation#8356
fix(install): skip tools=true env directives during backend installation#8356
Conversation
During tool installation, backends (cargo, npm, pipx) called
env_with_path() which resolves `tools = true` env directives. These
directives may reference tools via templates like
`{{ tools.node.version }}`, but the referenced tools might not be
installed yet, causing template rendering errors.
Add env_with_path_without_tools() that includes tool paths in PATH but
skips `tools = true` env directive resolution, mirroring the approach
already used for preinstall hooks (full_env_without_tools). Update all
backend install callsites to use this method.
Fixes #8346
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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 preventing successful installation of certain tools when environment variables with 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 crash that occurs during tool installation when tools = true environment directives are present. The approach of introducing env_with_path_without_tools to defer the resolution of these directives is sound, and the updates to the cargo, npm, and pipx backends are appropriate. The addition of an end-to-end test is also a great way to ensure this issue doesn't regress. I have one suggestion to reduce code duplication.
src/toolset/toolset_env.rs
Outdated
| let (tool_env, add_paths) = self.env(config).await?; | ||
| let mut env: EnvMap = env::PRISTINE_ENV.clone().into_iter().collect(); | ||
| env.extend(tool_env); | ||
| let mut path_env = PathEnv::from_iter(env::PATH.clone()); | ||
| for p in config.path_dirs().await?.clone() { | ||
| path_env.add(p); | ||
| } | ||
| for p in &add_paths { | ||
| path_env.add(p.clone()); | ||
| } | ||
| for p in self.list_paths(config).await { | ||
| path_env.add(p); | ||
| } | ||
| env.insert(PATH_KEY.to_string(), path_env.to_string()); | ||
| Ok(env) |
There was a problem hiding this comment.
This function's implementation is identical to full_env_without_tools. To avoid code duplication, you can refactor this to call full_env_without_tools directly.
| let (tool_env, add_paths) = self.env(config).await?; | |
| let mut env: EnvMap = env::PRISTINE_ENV.clone().into_iter().collect(); | |
| env.extend(tool_env); | |
| let mut path_env = PathEnv::from_iter(env::PATH.clone()); | |
| for p in config.path_dirs().await?.clone() { | |
| path_env.add(p); | |
| } | |
| for p in &add_paths { | |
| path_env.add(p.clone()); | |
| } | |
| for p in self.list_paths(config).await { | |
| path_env.add(p); | |
| } | |
| env.insert(PATH_KEY.to_string(), path_env.to_string()); | |
| Ok(env) | |
| self.full_env_without_tools(config).await |
There was a problem hiding this comment.
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.
Greptile SummaryFixed crash during tool installation when config contains The solution adds Key changes:
Note: Minor code duplication exists between Confidence Score: 4/5
Important Files Changed
Last reviewed commit: 866ac31 |
| pub async fn env_with_path_without_tools(&self, config: &Arc<Config>) -> Result<EnvMap> { | ||
| let (tool_env, add_paths) = self.env(config).await?; | ||
| let mut env: EnvMap = env::PRISTINE_ENV.clone().into_iter().collect(); | ||
| env.extend(tool_env); | ||
| let mut path_env = PathEnv::from_iter(env::PATH.clone()); | ||
| for p in config.path_dirs().await?.clone() { | ||
| path_env.add(p); | ||
| } | ||
| for p in &add_paths { | ||
| path_env.add(p.clone()); | ||
| } | ||
| for p in self.list_paths(config).await { | ||
| path_env.add(p); | ||
| } | ||
| env.insert(PATH_KEY.to_string(), path_env.to_string()); | ||
| Ok(env) |
There was a problem hiding this comment.
This method duplicates the logic of full_env_without_tools() (lines 27-42). Consider refactoring to avoid duplication by having one call the other, or extracting the shared logic into a private helper method.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Hyperfine Performance
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.2.21 x -- echo |
27.1 ± 0.5 | 25.9 | 31.3 | 1.00 |
mise x -- echo |
27.1 ± 3.7 | 25.4 | 96.7 | 1.00 ± 0.14 |
mise env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.2.21 env |
26.5 ± 0.7 | 25.1 | 34.6 | 1.00 |
mise env |
26.7 ± 0.7 | 25.2 | 35.8 | 1.01 ± 0.04 |
mise hook-env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.2.21 hook-env |
27.0 ± 0.6 | 25.4 | 31.2 | 1.00 |
mise hook-env |
27.4 ± 0.6 | 25.9 | 31.8 | 1.01 ± 0.03 |
mise ls
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.2.21 ls |
25.5 ± 0.5 | 24.0 | 26.7 | 1.00 |
mise ls |
25.7 ± 0.7 | 24.4 | 34.8 | 1.01 ± 0.03 |
xtasks/test/perf
| Command | mise-2026.2.21 | mise | Variance |
|---|---|---|---|
| install (cached) | 163ms | 162ms | +0% |
| ls (cached) | 93ms | 92ms | +1% |
| bin-paths (cached) | 98ms | 96ms | +2% |
| task-ls (cached) | 867ms | 858ms | +1% |
The previous implementation incorrectly started from PRISTINE_ENV (the full process environment), but env_with_path does not include it. This caused the full process environment to be passed to backends, overriding explicitly-set env vars like GITHUB_TOKEN during cargo-binstall. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…th_without_tools Have full_env_without_tools delegate to env_with_path_without_tools instead of duplicating the path-building logic. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
### 🚀 Features - add `--outdated` flag to `mise plugins ls` by @jdx in [#8360](#8360) ### 🐛 Bug Fixes - **(github)** resolve rename_exe search dir for archives with bin/ subdirectory by @jdx in [#8358](#8358) - **(install)** skip tools=true env directives during backend installation by @jdx in [#8356](#8356) - **(ruby)** resolve correct Windows checksums in lockfile by @jdx in [#8357](#8357) ### 📦 Registry - switch terradozer backend to github fork by @chenrui333 in [#8365](#8365) ### Chore - **(release)** fix duplicated version prefix in release title by @jdx in [#8359](#8359) ### New Contributors - @chenrui333 made their first contribution in [#8365](#8365) ## 📦 Aqua Registry Updates #### New Packages (1) - [`huseyinbabal/taws`](https://github.com/huseyinbabal/taws) #### Updated Packages (2) - [`block/goose`](https://github.com/block/goose) - [`pre-commit/pre-commit`](https://github.com/pre-commit/pre-commit)
…ion (jdx#8356) ## Summary - Fix crash when installing cargo/npm/pipx tools alongside `tools = true` env directives that reference other tools (e.g., `{{ tools.node.version }}`) - During installation, referenced tools may not be installed yet, causing template rendering to fail with "Variable not found in context" - Add `env_with_path_without_tools()` that includes tool paths in PATH but skips `tools = true` env directive resolution, mirroring the approach already used for preinstall hooks - Update cargo, npm, and pipx backends to use this method during installation Fixes jdx#8346 ## Test plan - [ ] New e2e test `test_install_with_tools_env` verifies `mise install` succeeds with `tools = true` env vars alongside npm tools - [ ] Unit tests pass (491/491) - [ ] Lint passes 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes tool-install-time environment construction for `cargo`/`npm`/`pipx`, which could affect installs that relied on `tools=true` env evaluation during install. Scope is limited and covered by a new regression e2e test. > > **Overview** > Fixes a crash during `mise install` when `[env]` contains `tools = true` directives that reference other tools not yet installed. > > Adds `Toolset::env_with_path_without_tools()` (and wires `full_env_without_tools()` through it) to build an install-time env that still sets up `PATH` but skips resolving `tools=true` env entries, then updates the `cargo`, `npm` (including `bun`/`pnpm` paths), and `pipx` backends to use it during installation. > > Adds an e2e regression test (`e2e/backend/test_install_with_tools_env`) that installs an npm tool alongside a `tools=true` env template and asserts `mise install` succeeds. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit d486725. 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 - add `--outdated` flag to `mise plugins ls` by @jdx in [jdx#8360](jdx#8360) ### 🐛 Bug Fixes - **(github)** resolve rename_exe search dir for archives with bin/ subdirectory by @jdx in [jdx#8358](jdx#8358) - **(install)** skip tools=true env directives during backend installation by @jdx in [jdx#8356](jdx#8356) - **(ruby)** resolve correct Windows checksums in lockfile by @jdx in [jdx#8357](jdx#8357) ### 📦 Registry - switch terradozer backend to github fork by @chenrui333 in [jdx#8365](jdx#8365) ### Chore - **(release)** fix duplicated version prefix in release title by @jdx in [jdx#8359](jdx#8359) ### New Contributors - @chenrui333 made their first contribution in [jdx#8365](jdx#8365) ## 📦 Aqua Registry Updates #### New Packages (1) - [`huseyinbabal/taws`](https://github.com/huseyinbabal/taws) #### Updated Packages (2) - [`block/goose`](https://github.com/block/goose) - [`pre-commit/pre-commit`](https://github.com/pre-commit/pre-commit)
Summary
tools = trueenv directives that reference other tools (e.g.,{{ tools.node.version }})env_with_path_without_tools()that includes tool paths in PATH but skipstools = trueenv directive resolution, mirroring the approach already used for preinstall hooksFixes #8346
Test plan
test_install_with_tools_envverifiesmise installsucceeds withtools = trueenv vars alongside npm tools🤖 Generated with Claude Code
Note
Medium Risk
Changes tool-install-time environment construction for
cargo/npm/pipx, which could affect installs that relied ontools=trueenv evaluation during install. Scope is limited and covered by a new regression e2e test.Overview
Fixes a crash during
mise installwhen[env]containstools = truedirectives that reference other tools not yet installed.Adds
Toolset::env_with_path_without_tools()(and wiresfull_env_without_tools()through it) to build an install-time env that still sets upPATHbut skips resolvingtools=trueenv entries, then updates thecargo,npm(includingbun/pnpmpaths), andpipxbackends to use it during installation.Adds an e2e regression test (
e2e/backend/test_install_with_tools_env) that installs an npm tool alongside atools=trueenv template and assertsmise installsucceeds.Written by Cursor Bugbot for commit d486725. This will update automatically on new commits. Configure here.