Skip to content

fix(exec): name installed-but-inactive tools on resolution failure - #11803

Merged
jdx merged 2 commits into
jdx:mainfrom
JamBalaya56562:fix/exec-inactive-installed-tool
Aug 9, 2026
Merged

jdx merged 2 commits into
jdx:mainfrom
JamBalaya56562:fix/exec-inactive-installed-tool

Conversation

@JamBalaya56562

@JamBalaya56562 JamBalaya56562 commented Aug 9, 2026 •

Copy link
Copy Markdown
Contributor

Closes #4407.

The report still reproduces

#4407 (Feb 2025, 5 👍, no replies) says mise install gh reports success but
gh is then not runnable. That is still true today, on both platforms — the
key detail is that the reporter had no gh of their own on PATH:

Windows, v2026.8.2 windows-x64, isolated MISE_DATA_DIR:

PS> mise install gh
mise gh@2.97.0     ✓ installed
PS> mise exec -- gh --version
mise ERROR cannot find binary path

Linux, v2026.8.3 linux-x64:

$ mise install usage
mise usage@5.0.0   ✓ installed
$ mise exec -- usage --version
mise ERROR "usage" couldn't exec process: No such file or directory

The install genuinely succeeded — the binary is on disk — and mise exec
genuinely cannot run it, because mise install writes to no config file and
mise exec builds its PATH from the tools in the config. So the failure is
correct. What is missing is any hint that mise itself put the tool there, or
that mise use <tool> / mise exec <tool> -- <tool> is one word away.

Since v2026.3.0 mise install does warn (installed but not activated — it is not in any config file), but that is printed at install time. The command that
actually fails, possibly much later, says nothing.

What this changes

Discussion #11183 already fixed exactly this shape for the shim dispatch
path — err_shim_not_found replaced cannot find binary path with actionable
guidance whenever __MISE_SHIM_PATH is set. The non-shim path was left as-is.
This covers it.

When a bin fails to resolve and an installed-but-unconfigured tool of that name
would have provided it, the existing error gains an explanation:

$ mise exec -- usage
mise ERROR "usage" couldn't exec process: No such file or directory

usage is installed but not activated — it is not in any config file.
To activate it, run:
  mise use usage
To run it without changing any config file, run:
  mise exec usage -- usage

The original error line is kept and appended to, not replaced: it is correct,
and it is what users search for.

  • Windows (exec.rs): the two non-shim arms that returned
    which::Error::CannotFindBinaryPath now go through a helper that appends the
    hint when there is one.
  • unix (exec.rs): the Err(_) => program fallback is deliberate — which
    can fail where exec still succeeds — so the branch is untouched. A flag
    records that resolution failed, and the hint is appended to the bail! that
    runs only after exec has definitively failed. No behaviour change, only
    message.
  • install_state::try_list_tools() is added alongside the existing
    try_list_plugins(). list_tools() panics when install state was never
    initialized, which is not acceptable on an error path.

Limitation, deliberate

Matching is by tool name, reusing BackendArg::matches_bin_name (which
already handles the Windows .exe suffix and case). So gh, jq, usage are
recognized; npm provided by node is not. In that case the helper returns
None and the caller keeps today's message — no regression, just no hint.
Resolving it properly would mean scanning every installed tool's bin dir, which
is too much for an error path.

The hint is also suppressed when a configured tool matches the bin: that
failure has a different cause, and err_no_version_set /
unavailable_configured_tool_message already explain it.

Out of scope

  • The macOS sandbox-exec bail! is a separate path and is not touched.
  • The mise install warning is unchanged — it is already correct.
  • tool_stub.rs shares exec_program, so it benefits without special-casing.

Tests

  • 3 unit tests in shims.rs covering: the message names the tool, a configured
    tool yields None, and a bin that does not name its tool yields None.
  • e2e/cli/test_exec_inactive_installed_tool — installs dummy without
    activating it, asserts the hint and that the suggested command works, and
    asserts an unknown bin keeps the original error untouched.
  • e2e-win/exec_inactive_tool.Tests.ps1 — same on Windows, using usage. It
    strips any host usage from PATH first; a preinstalled copy would resolve
    and mask the failure (that is exactly the trap I fell into while measuring
    this originally).

Existing assertions on couldn't exec process / cannot find binary path
(e2e/config/test_auto_install_false,
e2e/config/test_config_auto_install_disable_tools) all pass the tool on the
exec line, so it is in the toolset and the hint is suppressed. They also match
by substring, so appended text could not break them either way.

I could not re-test the reporter's own v2025.2.4: that binary can no longer
install anything, as https://mise-versions.jdx.dev/aqua-registry/cli/cli/registry.yaml
now returns 400.

Summary by CodeRabbit

  • New Features

    • Improved mise exec errors when an installed tool is not activated.
    • Added actionable commands to activate the tool or run it directly.
    • Preserved existing errors for unavailable or incompatible tools.
    • Added consistent behavior across Unix and Windows.
  • Tests

    • Added regression coverage for inactive installed tools, suggested commands, successful execution, and unchanged unknown-tool errors.

`mise install <tool>` deliberately writes to no config file, so the tool's
bin dir never joins the PATH `mise exec` builds. Resolution then fails
legitimately -- but with no hint that mise had just installed the tool:
`cannot find binary path` on Windows, a bare ENOENT on unix.

Discussion jdx#11183 already fixed this shape for the shim dispatch path;
this covers the remaining non-shim one. When an installed-but-unconfigured
tool would have provided the bin, append what it is and how to reach it.

Matching is by tool name, so `npm` from `node` is not recognized; those
callers keep the existing message rather than getting a wrong one.

Closes jdx#4407
@coderabbitai

coderabbitai Bot commented Aug 9, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 3ac8fd2c-7c5f-4c8c-ac40-d780465282d7

📥 Commits

Reviewing files that changed from the base of the PR and between 36c59ea and 1aaade6.

📒 Files selected for processing (1)
  • src/shims.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/shims.rs

📝 Walkthrough

Walkthrough

mise exec now reports activation guidance when an installed tool is inactive and unavailable through PATH. The change covers Unix and Windows resolution paths, preserves existing unknown-tool and shim errors, and adds regression tests.

Changes

Inactive tool execution diagnostics

Layer / File(s) Summary
Resolution hint generation
src/shims.rs, src/toolset/install_state.rs
The shim layer matches unresolved binaries to installed, unconfigured tools and suggests mise use or mise exec. Install state can now be queried without panicking when uninitialized.
Execution error integration
src/cli/exec.rs
Unix and Windows execution paths preserve the requested program name, track failed PATH resolution, and append inactive-tool hints while retaining shim-specific errors.
Cross-platform regression coverage
e2e/cli/test_exec_inactive_installed_tool, e2e-win/exec_inactive_tool.Tests.ps1
Tests cover inactive installed tools, explicit activation, unknown tools, isolated PATH handling, and cleanup.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant MiseExec
  participant ToolResolver
  participant InstallState
  User->>MiseExec: run inactive tool
  MiseExec->>ToolResolver: resolve program through PATH
  ToolResolver-->>MiseExec: resolution failure
  MiseExec->>InstallState: check installed tools
  InstallState-->>MiseExec: installed inactive tool
  MiseExec-->>User: show mise use or mise exec guidance
Loading

Possibly related PRs

  • jdx/mise#11189: Both improve unresolved tool diagnostics in src/cli/exec.rs and src/shims.rs.
  • jdx/mise#11398: Both add tool-aware executable resolution logic in src/shims.rs.
  • jdx/mise#11666: Both modify tool-aware shim resolution flows in src/shims.rs.

Poem

A tool sleeps, installed but unseen,
Until mise use makes it keen.
Or mise exec leads the way,
On Unix and Windows in one day.
Tests hop behind it, bright and clean.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: identifying installed but inactive tools when resolution fails.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@JamBalaya56562
JamBalaya56562 marked this pull request as ready for review August 9, 2026 14:06
@greptile-apps

greptile-apps Bot commented Aug 9, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR improves failed mise exec diagnostics by identifying installed-but-inactive tools and suggesting commands to activate or run them, while preserving existing errors for unrelated failures.

  • Adds Unix and Windows resolution-failure hints.
  • Uses configured-tool and enable/disable state to avoid misleading guidance.
  • Adds non-panicking install-state access for the diagnostic path.
  • Adds Unix, Windows, and unit regression coverage.

Confidence Score: 5/5

The PR appears safe to merge.

The previously reported configured-tool misclassification is fixed, and no blocking failure remains.

Important Files Changed

Filename Overview
src/shims.rs Generates inactive-tool guidance and now correctly suppresses it for configured, disabled, unsupported, or unresolved tools.
src/cli/exec.rs Appends actionable guidance only after command resolution and execution have definitively failed.
src/toolset/install_state.rs Adds a non-panicking accessor suitable for best-effort diagnostic paths.
e2e/cli/test_exec_inactive_installed_tool Covers inactive installed tools, successful suggested execution, and unchanged unknown-command errors on Unix.
e2e-win/exec_inactive_tool.Tests.ps1 Covers equivalent inactive-tool diagnostics and suggested execution on Windows.

Reviews (3): Last reviewed commit: "fix(exec): treat a declared-but-unresolv..." | Re-trigger Greptile

Comment thread src/shims.rs Resolved
@JamBalaya56562
JamBalaya56562 marked this pull request as draft August 9, 2026 14:12
@JamBalaya56562
JamBalaya56562 marked this pull request as ready for review August 9, 2026 14:13
list_current_versions() drops a tool whose version failed to resolve, whose
OS is unsupported, or whose backend could not be built, so the hint could
tell a user that a tool sitting in their config file "is not in any config
file". Check the toolset's declared keys instead, which survive all three.

A disabled tool never reaches that check at all -- Toolset::add_version
skips it -- so filter disabled tools out of the installed candidates too,
where the same wrong advice would otherwise apply.
@jdx
jdx enabled auto-merge (squash) August 9, 2026 14:30
@jdx
jdx merged commit 23f8607 into jdx:main Aug 9, 2026
30 checks passed
@JamBalaya56562
JamBalaya56562 deleted the fix/exec-inactive-installed-tool branch August 9, 2026 15:07
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