jdx/mise · error
no version specified for tool {tool}\nuse `mise shell {tool}
Error message
no version specified for tool {tool}\nuse `mise shell {tool}@VERSION` to set a version What it means
`mise shell` sets per-session tool versions by exporting env vars like MISE_NODE_VERSION via the activate hook; each TOOL argument must be TOOL@VERSION because the whole point is pinning a concrete version in the current session. The loop over self.tool bails on the first ToolArg whose tvr (tool version request) is None — unless --unset was given, which is checked first. The command also requires an activated session and a detectable shell before reaching this check.
Source
Thrown at src/cli/shell.rs:62
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 6f52dcdf99)
Solutions
- Include the version exactly as the message hints: `mise shell node@22`
- To remove a session pin instead, use the unset form: `mise shell --unset node`
- For a persistent per-project version, use `mise use node@22` (writes config) rather than `mise shell`
Example fix
# before mise shell node # no version specified for tool node; use `mise shell node@VERSION` # after mise shell node@22 # to clear it later: mise shell -u node
Defensive patterns
Strategy: validation
Validate before calling
# require TOOL@VERSION before calling mise shell
for t in "$@"; do
case "$t" in
*@*) ;;
*) echo "usage: mise shell TOOL@VERSION (got: $t)" >&2; exit 2;;
esac
done
mise shell "$@" Type guard
has_version_spec() { case "$1" in *@*) return 0;; *) return 1;; esac; } Try / catch
Catch 'no version specified', append @<version> to the offending tool (named in the message), and rerun once; if the intent was clearing the pin, rerun with `mise shell -u <tool>`.
Prevention
- Remember `mise shell` always pins: TOOL@VERSION, no exceptions except --unset
- Use `mise use` for persistent versions and `mise shell` for session pins
- Guard wrapper scripts with a TOOL@* pattern check
When it happens
Trigger: Running `mise shell node` (no @VERSION) inside an activated session; passing a bare tool name when intending to pin a version; note `mise shell -u node` (unset) is the valid form without a version.
Common situations: Muscle memory from `mise use node`-style commands; forgetting the @ syntax in shell rc snippets or docs copied from `mise use` examples; scripting session setup quickly.
Related errors
- trimV requires exactly 1 argument
- action prediction payload is too large
- task action manifest has an invalid identity
- task action manifest contains duplicate predictions
- remote action manifest keys must use blake3
AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22).
Data as JSON: /api/errors/33373bd078688d92.
Report an issue: GitHub.