jdx/mise · error · eyre::Report

{}@{requested} is not installed{resolved} hint: run `mise in

Error message

{}@{requested} is not installed{resolved}
hint: run `mise install {}@{requested}`, or `mise ls {}` to see installed versions

What it means

Raised by `mise which BIN --tool=tool@version`. The `--tool` flag replaces the configured toolset for the lookup, and `Which::uninstalled_tool_message` (src/cli/which.rs:105) detects that the requested (or resolved) version of that tool is not actually installed, so there is nothing to resolve BIN against. The message includes the resolved version when a fuzzy request like `--tool=node@20` resolved to something else.

Source

Thrown at src/cli/which.rs:61

        }
        let ts = self.get_toolset(&config).await?;

        let bin_name = self.bin_name.clone().unwrap();
        match ts.which(&config, &bin_name).await {
            Some((p, tv)) => {
                if self.version {
                    miseprintln!("{}", tv.version);
                } else if self.plugin {
                    miseprintln!("{p}");
                } else {
                    let path = p.which(&config, &tv, &bin_name).await?;
                    miseprintln!("{}", path.unwrap().display());
                }
                Ok(())
            }
            None => {
                if let Some(msg) = self.uninstalled_tool_message(&config, &ts) {
                    bail!(msg);
                }
                if let Some(msg) =
                    crate::shims::unavailable_configured_tool_message(&config, &ts, &bin_name)
                {
                    bail!(msg);
                }
                if self.has_shim(&bin_name) {
                    bail!(
                        "{bin_name} is a mise bin however it is not currently active. Use `mise use` to activate it in this directory."
                    )
                } else {
                    bail!("{bin_name} is not a mise bin. Perhaps you need to install it first.",)
                }
            }
        }
    }
    async fn complete(&self, config: &Arc<Config>) -> Result<()> {
        let ts = self.get_toolset(config).await?;

View on GitHub (pinned to 6f52dcdf99)

Solutions

  1. Run the hint in the message: `mise install <tool>@<requested>`
  2. Check what is installed with `mise ls <tool>` and pass an installed version to `--tool`
  3. Drop `--tool` entirely so `mise which` uses the configured toolset
  4. Run plain `mise install` to install everything pinned by the current config

Example fix

# before
mise which npm --tool=node@20   # node@20 not installed

# after
mise install node@20
mise which npm --tool=node@20
Defensive patterns

Strategy: validation

Validate before calling

# ensure the version exists before probing with --tool
mise ls --installed node | grep -qx '20.11.1' || mise install node@20.11.1
mise which npm --tool=node@20.11.1

Prevention

When it happens

Trigger: `mise which npm --tool=node@20` when node@20 (or the release `20` resolves to) is not in the installs dir; using `--tool` on a fresh machine before `mise install`; pointing `--tool` at a version removed by `mise prune`. It only fires when `--tool` was passed — without it, mise falls through to the config-based errors.

Common situations: Fresh clone where mise.toml pins a version that was never installed; scripts that probe a specific version with `--tool` after a cleanup; typos in the version string so a different (uninstalled) release is resolved.

Related errors


AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22). Data as JSON: /api/errors/89b8979158b81384. Report an issue: GitHub.