Skip to content

fix(shim): skip network resolution for installed tool dirs#9599

Merged
jdx merged 3 commits intomainfrom
fix/reshim-stale-installs
May 5, 2026
Merged

fix(shim): skip network resolution for installed tool dirs#9599
jdx merged 3 commits intomainfrom
fix/reshim-stale-installs

Conversation

@jdx
Copy link
Copy Markdown
Owner

@jdx jdx commented May 4, 2026

Summary

Toolset::list_installed_versions was calling ToolRequest::resolve() on every on-disk install that wasn't part of the current toolset. For a stale install dir literally named latest (left over from when a tool was once requested as tool = "latest"), this re-queries the registry — and a 404 from the upstream (e.g. facebook/buck2 doesn't publish a "latest" GitHub release) bubbles ? all the way up and aborts the entire reshim with failed to rebuild shims: no versions found for buck2.

Two issues fixed:

  1. No need to re-resolve. The version string came from b.list_installed_versions(), which reads ~/.mise/installs/<tool>/ directory names — i.e. it's already a concrete version. Construct ToolVersion::new(req, v) directly instead of calling .resolve() (no network).
  2. One bad install shouldn't break everything. Per-tool ToolRequest::new errors are now warned-and-skipped, matching the existing pattern at src/shims.rs:494-499 for list_tool_bins.

Repro (before fix)

mkdir -p ~/.mise/installs/buck2/latest/bin
touch ~/.mise/installs/buck2/latest/bin/buck2
mise reshim
# ERROR failed to rebuild shims
# ERROR no versions found for buck2

After this fix, reshim succeeds and the buck2 shim is created from the on-disk install.

Test plan

  • cargo test --bin mise toolset — 47 passing
  • Manual repro of the buck2 case above — reshim now succeeds (exit 0)
  • mise dr no longer reports stale-install resolution failures
  • CI

🤖 Generated with Claude Code


Note

Medium Risk
Changes how mise reshim discovers installed versions by skipping remote resolution and ignoring per-install parse failures, which could affect shim generation for edge-case version directory names. Scope is small but touches core shim rebuild behavior used frequently.

Overview
Fixes mise reshim failures caused by stale install directories with non-resolvable version names (e.g. an on-disk latest directory when offline). Toolset::list_installed_versions now treats install dir names as already-concrete versions (no .resolve()/network) and logs+skips per-tool request construction errors instead of aborting the entire shim rebuild.

Adds an e2e regression test (e2e/cli/test_reshim_stale_install) that fabricates a stale buck2/latest install and asserts MISE_OFFLINE=1 mise reshim still completes and creates shims for a real installed tool.

Reviewed by Cursor Bugbot for commit f86e33e. Bugbot is set up for automated code reviews on this repo. Configure here.

`Toolset::list_installed_versions` was calling `.resolve()` on each
on-disk install — for a stale dir literally named `latest`, this
re-queries the registry and fails on 404 (e.g. `facebook/buck2` has no
"latest" GitHub release), aborting reshim entirely. The dir name is
already the concrete version, so construct `ToolVersion` directly and
warn-and-skip on per-tool errors so one bad install can't break the
whole rebuild.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
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 updates the list_installed_versions method in src/toolset/mod.rs to improve performance and robustness. The code now avoids unnecessary network calls by removing the .resolve() call on version strings already present on disk. Additionally, error handling has been improved to log warnings for individual tool failures rather than aborting the entire listing process, and the config parameter is now marked as unused. I have no feedback to provide.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 4, 2026

Greptile Summary

This PR fixes Toolset::list_installed_versions from calling .resolve() (which hits the network) for every on-disk install directory not in the current toolset. It replaces that with direct ToolVersion::new(req, version) construction and changes per-tool ToolRequest::new failures from fatal to warn-and-skip, preventing a single stale install dir (e.g. buck2/latest) from aborting mise reshim with a 404 error.

The approach is sound: directory names returned by b.list_installed_versions() are already-concrete versions, so re-resolution is unnecessary. The normalization of ref-mainref:main via req.version() is correctly called out in a code comment, and the warn-and-skip pattern matches existing usage at src/shims.rs:494-499.

Confidence Score: 5/5

Safe to merge — narrowly scoped fix with no P0/P1 findings and a regression test covering the exact failure scenario.

No P0 or P1 issues found. The change correctly eliminates unnecessary network resolution for already-concrete on-disk install versions, the warn-and-skip pattern matches existing codebase conventions, the req.version() normalization is intentional and commented, and the _config unused-parameter annotation is correct. The e2e test validates the regression scenario end-to-end.

No files require special attention.

Important Files Changed

Filename Overview
src/toolset/mod.rs Replaces network-backed .resolve() with direct ToolVersion::new construction for on-disk installs, and demotes per-tool ToolRequest::new failures from fatal to warn-and-skip. Logic is correct and well-commented.
e2e/cli/test_reshim_stale_install New e2e regression test that fabricates a stale buck2/latest install dir and asserts MISE_OFFLINE=1 mise reshim still completes and creates the dummy shim. Covers the core abort-prevention scenario.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["list_installed_versions()"] --> B["list_current_versions() → HashMap"]
    B --> C["for b in backend::list()"]
    C --> D["for v in b.list_installed_versions()"]
    D --> E{v in current_versions?}
    E -- yes --> F["push existing TVTuple"]
    E -- no --> G["ToolRequest::new(ba, v, Unknown)"]
    G -- Ok --> H["req.version() — normalize ref-X to ref:X"]
    H --> I["ToolVersion::new(req, version) — no network, no .resolve()"]
    I --> J["push to versions"]
    G -- Err --> K["warn! and skip — was: ? propagate → abort"]
    F --> L["return Ok(versions)"]
    J --> L
    K --> L
Loading

Fix All in Claude Code

Reviews (3): Last reviewed commit: "fix(shim): match ToolVersion.version to ..." | Re-trigger Greptile

Reproduces the buck2 case from the previous commit: a github-backed
install dir literally named `latest` registered in the install manifest,
combined with `MISE_OFFLINE=1`, makes resolution return
`no versions found for buck2`. Verified to fail against the pre-fix
`Toolset::list_installed_versions` and pass after.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Copy link
Copy Markdown

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

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit b76aee4. Configure here.

Comment thread src/toolset/mod.rs Outdated
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 4, 2026

Hyperfine Performance

mise x -- echo

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.5.0 x -- echo 68.3 ± 6.3 36.1 89.6 1.00
mise x -- echo 69.5 ± 6.4 38.4 98.7 1.02 ± 0.13

mise env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.5.0 env 67.2 ± 6.5 35.2 86.9 1.04 ± 0.18
mise env 64.5 ± 8.9 26.3 105.3 1.00

mise hook-env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.5.0 hook-env 69.0 ± 7.1 32.1 89.6 1.00
mise hook-env 69.3 ± 7.0 32.7 91.3 1.01 ± 0.14

mise ls

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.5.0 ls 59.6 ± 6.5 31.8 73.5 1.20 ± 0.25
mise ls 49.9 ± 9.1 28.3 78.2 1.00
✅ Performance improvement for ls is 20%

xtasks/test/perf

Command mise-2026.5.0 mise Variance
install (cached) 254ms 252ms +0%
ls (cached) 156ms ⚠️ 183ms -14%
bin-paths (cached) 177ms 178ms +0%
task-ls (cached) 870ms 871ms +0%

⚠️ Warning: ls cached performance variance is -14%

Cursor Bugbot caught: for install dirs with ref/tag/branch/rev prefixes
(e.g. `ref-main`), `ToolRequest::new` normalizes the hyphenated dir name
to colon form (`ref:main`) and builds a `Ref` variant whose
`request.version()` returns `"ref:main"`. Passing the raw `v`
(`"ref-main"`) to `ToolVersion::new` left `tv.version` and
`tv.request.version()` inconsistent — the old `.resolve()` path used
`request.version()`, so callers (`mise ls`, etc.) expect that
invariant. Fix: use `req.version()` as the version field.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@jdx jdx merged commit f5df673 into main May 5, 2026
36 checks passed
@jdx jdx deleted the fix/reshim-stale-installs branch May 5, 2026 02:10
mise-en-dev added a commit that referenced this pull request May 5, 2026
### 🚀 Features

- **(backend)** support top-level aqua cosign verification by @risu729
in [#9111](#9111)

### 🐛 Bug Fixes

- **(schema)** validate all schema files with draft2020 and strict mode
by @risu729 in [#9594](#9594)
- **(shim)** skip network resolution for installed tool dirs by @jdx in
[#9599](#9599)

### 📚 Documentation

- **(dev-tools)** clarify vfox metadata depends for install hooks by
@risu729 in [#9573](#9573)
- **(plugins)** remove registry submission guidance by @risu729 in
[#9577](#9577)

### 📦️ Dependency Updates

- lock file maintenance by @renovate[bot] in
[#9586](#9586)

### 📦 Registry

- remove bashly asdf fallback by @risu729 in
[#9578](#9578)
- use github backend for rebar by @risu729 in
[#9576](#9576)
- add wasm-tools
([aqua:bytecodealliance/wasm-tools](https://github.com/bytecodealliance/wasm-tools))
by @2xdevv in [#9596](#9596)
- enable symlink_bins for elixir-ls by @AlternateRT in
[#9592](#9592)

### Chore

- **(release)** always append sponsor block to release notes by @jdx in
[#9580](#9580)
- warn on vendored vfox embedded plugins by @risu729 in
[#9588](#9588)
- prefer registry shorthands over cargo/npm backends in mise.toml by
@risu729 in [#9595](#9595)

## 📦 Aqua Registry Updates

### New Packages (2)

-
[`salesforce/reactive-grpc/protoc-gen-reactor-grpc`](https://github.com/salesforce/reactive-grpc)
- [`spinframework/spin`](https://github.com/spinframework/spin)

### Updated Packages (1)

- [`pnpm/pnpm`](https://github.com/pnpm/pnpm)
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