jdx/mise · error
command wrapper for {shim_name} cannot delegate to itself
Error message
command wrapper for {shim_name} cannot delegate to itself What it means
mise allows configuring command wrappers that delegate shim invocations to a different command, but a wrapper whose command equals the shim's own name would recurse infinitely. which_shim detects this self-delegation and aborts before dispatching.
Source
Thrown at src/shims.rs:236
.with_resolve_options(resolve_options)
.build(config)
.await?;
let wrappers = load_command_wrappers(
&config.config_files,
ts.versions.values().flat_map(|versions| &versions.requests),
)?;
validate_wrapper_names(wrappers.keys())?;
let wrapper = if cfg!(macos) {
wrappers
.iter()
.find(|(name, _)| command_names_eq(name, shim_name))
.map(|(_, wrapper)| wrapper)
} else {
wrappers.get(shim_name)
};
if let Some(wrapper) = wrapper {
if command_names_eq(wrapper.command(), shim_name) {
bail!("command wrapper for {shim_name} cannot delegate to itself");
}
trace!("shim[{bin_name}] WRAPPER command: {}", wrapper.command());
return Ok((PathBuf::from(wrapper.command()), ts, Some(wrapper.clone())));
}
// A configured tool may intentionally override an executable bundled by another installed
// tool (for example, a pinned npm overrides Node's npm). Install a missing provider declared
// by the registry before resolving an incidental installed provider.
if !completion_offline
&& Settings::get().not_found_auto_install
&& ts
.should_install_missing_registry_bin_provider(config, shim_name)
.await?
{
for tv in ts
.install_missing_bin(config, shim_name)
.await?
.unwrap_or_default()
{View on GitHub (pinned to afd2eddd3a)
Solutions
- Point the wrapper command at the real underlying executable path (e.g. ~/.local/share/mise/installs/<tool>/.../bin/foo) instead of the bare name.
- Rename the wrapper to a different command name than the target tool.
- Remove the wrapper if it provides no value and call the tool directly.
- Check `mise wrapper list` / relevant config to find the offending wrapper entry.
Example fix
// before (mise.toml) [wrapper] node = "node --max-old-space-size=4096" // delegates to itself // after [wrapper] node = "/home/me/.local/share/mise/installs/node/20/bin/node --max-old-space-size=4096"
Defensive patterns
Strategy: validation
Validate before calling
# bash: ensure wrapper command differs from the wrapper name before writing config
name="node"; cmd="node --max-old-space-size=4096"
[ "$name" = "$(echo "$cmd" | awk '{print $1}')" ] && echo "wrapper $name delegates to itself — point it at the real binary path" Prevention
- Wrapper commands must point at a different executable than the wrapper name.
- Use absolute paths to the underlying tool binary in wrapper commands.
- After editing wrappers, run the command once to verify no self-delegation error.
- Name wrappers distinctly (e.g. node-heap4g) when they merely add flags.
When it happens
Trigger: Configuring a command wrapper (in mise.toml wrapper/command-wrapper config) for tool `foo` whose resolved command is `foo` itself — e.g. `[wrapper] foo = "foo --flag"` or an absolute path that resolves to the same command name.
Common situations: Users intending to wrap a tool with extra flags but forgetting the wrapper must point at a *different* executable (or a full path to the real tool binary), so the wrapper name and target command collide.
Related errors
- recursive shim invocation detected for {bin_name}: {}
- invalid command wrapper name: {name:?}
- command wrapper names cannot contain dots on Windows: {name:
- {bin_name} is a mise bin however it is not currently active.
- failed to parse registry option {k} as a TOML value: {e}
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/8b627bfa9207b716.
Report an issue: GitHub.