jdx/mise · error
recursive shim invocation detected for {bin_name}: {}
Error message
recursive shim invocation detected for {bin_name}: {} What it means
Windows-only recursion guard in shim execution: mise stores the invoking shim's path in the MISE_SHIM_PATH environment variable; when a shim runs, it canonicalizes that previous value and compares it to the current shim path. If they are equal, the shim is about to execute itself and mise bails immediately instead of recursing until the process stack or PATH resolution explodes. Non-Windows platforms skip this check entirely.
Source
Thrown at src/shims.rs:44
pub async fn handle_shim() -> Result<()> {
// TODO: instead, check if bin is in shims dir
let bin_name = *env::MISE_BIN_NAME;
if env::is_mise_binary(bin_name) || cfg!(test) {
return Ok(());
}
#[cfg(windows)]
{
let shim_path = invoked_shim_path();
if env::var_path(env::MISE_SHIM_PATH_ENV)
.as_ref()
.is_some_and(|previous| {
file::paths_eq(
&file::canonicalize_or_self(previous),
&file::canonicalize_or_self(&shim_path),
)
})
{
bail!(
"recursive shim invocation detected for {bin_name}: {}",
display_path(&shim_path)
);
}
*env::MISE_SHIM_PATH.write().unwrap() = Some(shim_path.clone());
env::set_var(env::MISE_SHIM_PATH_ENV, &shim_path);
}
let mut config = Config::get().await?;
let mut args = env::ARGS.read().unwrap().clone();
env::PREFER_OFFLINE.store(true, Ordering::Relaxed);
trace!("shim[{bin_name}] args: {}", args.join(" "));
let (bin, ts) = which_shim(&mut config, &env::MISE_BIN_NAME, &args).await?;
args[0] = bin.to_string_lossy().to_string();
env::set_var("__MISE_SHIM", "1");
let exec = Exec {
tool: vec![],
c: None,
command: Some(args),View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Run `mise which <bin>` to find the real executable and make wrapper/child scripts call that absolute path instead of the bare command name.
- Reinstall the tool (`mise install <tool>@<version>`) if the real binary was removed, then `mise reshim`.
- Fix PATH ordering inside scripts: the activated tool's install dir must come before (or instead of) the shims dir when re-invoking tools.
- Rename any custom wrapper so it does not collide with the shim/bin name it delegates to.
Example fix
# before: wrapper re-invokes 'node', which resolves to the same shim node server.js # after: resolve the real binary first "$(mise which node)" server.js
Defensive patterns
Strategy: validation
Validate before calling
# Windows wrapper scripts: resolve the real binary instead of the bare name
bin=$(mise which node) || { echo 'node not installed' >&2; exit 1; }
"$bin" server.js Try / catch
Catch the 'recursive shim invocation detected' message from mise on Windows; report the offending shim path and instruct fixing PATH ordering or reinstalling — do not re-run the same command.
Prevention
- Never make a wrapper with the same filename as the bin it delegates to.
- In child scripts, call toolchain binaries via `mise which <bin>` or the activated install dir, not the shims dir.
- After uninstalling tools, run `mise reshim` so stale shims are pruned.
When it happens
Trigger: On Windows, a shim's target re-executes the same command name in a way that resolves back to the same shim file — e.g. a tool wrapper script calling `node` when the shims directory is the only source of `node` on PATH, or a shim/launcher named identically to the bin it wraps. Detected via env::MISE_SHIM_PATH matching invoked_shim_path().
Common situations: Custom wrapper scripts in the shims dir or earlier on PATH that re-exec the tool by name; tools that spawn themselves (language servers, watchers) while the real toolchain directory is not on PATH inside the child; broken installs where the real executable was deleted so the shim keeps resolving to itself; scripts that prepend the shims dir over the activated tool bin dir.
Related errors
- Infinitive loop detected, all tasks are finished but the gra
- {msg}
- --localized-dir {raw:?} cannot be carried to Windows: {bad:?
- cannot write Windows launcher because {} is not a generated
- cannot write Windows launcher because {} is not a regular fi
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/7ca8698865ff1e33.
Report an issue: GitHub.