jdx/mise · error

no version specified for tool

Error message

no version specified for tool {tool}
use `mise shell {tool}@VERSION` to set a version

What it means

`mise shell <tool>` pins tools in the current shell session, which requires an explicit version. If a tool argument is given without an @VERSION suffix (its ToolRequest has no version), mise cannot know what to activate and aborts, suggesting the correct syntax. This prevents silently activating whatever version happens to resolve.

Solutions

  1. Append a version: `mise shell node@22` (or a full version like node@22.3.0).
  2. Use `mise ls-remote node` to pick an available version.
  3. If you want the config-resolved version, use `mise exec`/activate via mise.toml instead of `mise shell` without a version.

Example fix

// before
mise shell node
// no version specified for tool node

// after
mise shell node@22
Defensive patterns

Strategy: validation

Validate before calling

case "$tool_spec" in *@*) : ;; *) echo "usage: mise shell ${tool_spec}@VERSION" >&2;; esac

Try / catch

mise shell node@22 || { mise ls-remote node | tail -1; }

Prevention

When it happens

Trigger: Running `mise shell node` (no @version) or `mise shell node@` — the tool argument parsed without a version range.

Common situations: Habit from `mise use node` (which can use config-resolved latest); copy-pasting commands omitting the version; scripting shell activation without knowing the desired version.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at src/cli/shell.rs:70

            err_inactive()?;
        }

        let shell = require_shell(
            None,
            &format!("Re-run `mise activate {EXAMPLE_SHELL}` in your shell rc file."),
        )?;

        if self.unset {
            for ta in &self.tool {
                let op = shell.unset_env(&tool_env_var_name(&ta.ba.short));
                print!("{op}");
            }
            return Ok(());
        }

        for ta in &self.tool {
            if ta.tvr.is_none() {
                bail!(
                    "no version specified for tool {tool}\nuse `mise shell {tool}@VERSION` to set a version",
                    tool = ta.ba.short,
                );
            }
        }

        let mut ts = ToolsetBuilder::new()
            .with_args(&self.tool)
            .build(&config)
            .await?;
        let opts = InstallOptions {
            force: false,
            jobs: self.jobs,
            raw: self.raw,
            ..Default::default()
        };
        let (_, missing) = ts.install_missing_versions(&mut config, &opts).await?;
        ts.notify_missing_versions(missing);

View on GitHub (pinned to 533346cc37)