jdx/mise · error

@ is not installed hint: run `mise install @ `, or `mise ls…

Error message

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

What it means

When `mise which <bin>` cannot find the binary in the active toolset, it first checks whether the bin belongs to a configured-but-uninstalled tool and, if so, bails with a message naming the tool@version and a hint to run `mise install`. This tells you the tool is in your config but its version is missing from the local install dir.

Solutions

  1. Run the hinted command: `mise install <tool>@<requested>` to install the exact version.
  2. List what is installed with `mise ls <tool>` and adjust the config pin to an installed version.
  3. Run `mise install` (no args) to install everything in the current config.

Example fix

// before
mise which terraform
// error: terraform@1.9.2 is not installed
// after
mise install terraform@1.9.2
mise which terraform
Defensive patterns

Strategy: fallback

Validate before calling

mise ls <tool> | grep -q <version> || mise install <tool>@<version>

Try / catch

if ! mise which "$bin" 2>/dev/null; then
  mise install
  mise which "$bin"
fi

Prevention

When it happens

Trigger: `mise which <bin>` where bin_name maps to a tool@requested in the toolset that has no installed path (`uninstalled_tool_message` returns Some) — i.e. the config pins a version that was never installed locally or was deleted.

Common situations: Fresh clone with a mise.toml/.tool-versions pinning versions never installed; switching toolsets and forgetting `mise install`; a cleaned ~/.local/share/mise/installs directory; lockfile referencing an uninstalled version.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/bddafe74c003d4ea. Report an issue: GitHub.

Appendix: source

Thrown at src/cli/which.rs:75

        }
        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 533346cc37)