jdx/mise · error
{msg}
Error message
{msg} What it means
mise exec / mise x tried to replace its own process with the requested program via exec(2) and the OS refused, almost always ENOENT because the binary was not on the PATH mise built for the active toolset. When mise knows an installed-but-unconfigured tool provides that bin, it appends a hint: `mise install` writes to no config file, so its tool dirs never join that PATH (discussion #4407). The raw program path and OS error are printed verbatim.
Source
Thrown at src/cli/exec.rs:424
if let Some(sandboxed) = sandbox.apply(&program.to_string_lossy(), &args_str).await? {
// macOS: exec through sandbox-exec
let err = exec::Command::new(&sandboxed.program)
.args(&sandboxed.args)
.exec();
bail!("{} {err}", sandboxed.program);
}
let err = exec::Command::new(program.clone()).args(&args).exec();
let mut msg = format!("{:?} {err}", program.to_string_lossy());
// The bin never resolved on PATH. If an installed-but-unconfigured tool
// would have provided it, say so instead of leaving the user with a bare
// ENOENT (discussion #4407).
if resolution_failed && let Some(hint) = crate::shims::exec_resolution_hint(&program_name).await
{
msg.push_str("\n\n");
msg.push_str(&hint);
}
bail!("{msg}")
}
/// The opaque `cannot find binary path`, plus an explanation when an
/// installed-but-unconfigured tool would have provided the bin. `mise install`
/// writes to no config file, so its tool dirs never join the PATH `mise exec`
/// builds (discussion #4407).
#[cfg(all(windows, not(test)))]
async fn err_cannot_find_binary_path(program_name: &str) -> eyre::Report {
let base: eyre::Report = which::Error::CannotFindBinaryPath.into();
match crate::shims::exec_resolution_hint(program_name).await {
Some(hint) => eyre!("{base}\n\n{hint}"),
None => base,
}
}
#[cfg(all(windows, not(test)))]
pub async fn exec_program<T, U>(
program: T,View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Add the tool to config so its dirs join the PATH mise exec builds: `mise use <tool>@<version>` (project) or `mise use -g <tool>` (global), then retry
- Verify resolution first: `mise which <bin>` — if that errors, the toolset does not provide the bin
- If the tool is only installed (not configured), either configure it with `mise use` or accept that `mise install` alone never puts it on mise exec's PATH (#4407)
- Check the spelling of the command against `mise ls` output and the tool's docs; some tools install bins under different names
- If the bin must come from the ambient shell, extend PATH in config (env._path / [env] PATH in mise.toml) or run it outside `mise exec`
Example fix
# before mise install node@22 mise exec -- prettier --check . # fails: prettier never configured, ENOENT # after mise use npm:prettier@3 mise exec -- prettier --check .
Defensive patterns
Strategy: validation
Validate before calling
#!/bin/bash # fail fast if the toolset cannot provide the bin if ! mise which "$BIN" >/dev/null 2>&1; then echo "mise: '$BIN' not provided by toolset; adding it" >&2 mise use "npm:$BIN" # or the backend that ships it fi mise exec -- "$BIN" "$@"
Try / catch
if ! mise exec -- "$BIN" "$@"; then
if ! mise which "$BIN" >/dev/null 2>&1; then
echo "config missing for $BIN — run: mise use <backend>:$BIN" >&2
fi
exit 1
fi Prevention
- Every tool a script execs must be declared in mise.toml/.tool-versions via `mise use`, not merely installed with `mise install`
- Add a CI smoke check after install: `mise which <bin>` for each required command before the real steps run
- Run `mise doctor` in onboarding to confirm the toolset resolves the bins you expect
- Prefer `mise x -- <backend>:<tool> -- <bin>` for one-off tool runs so the dependency is explicit
When it happens
Trigger: Running `mise exec -- <bin>` or `mise x -- <bin>` where <bin> resolves on neither the ambient PATH nor the toolset PATH: tool installed via `mise install <tool>` without ever being added to mise.toml/.tool-versions, tool listed in a config that is not loaded in this directory, typo in the command name, or the tool's version was never actually installed.
Common situations: CI installs tools with `mise install` but the project config never lists them, so `mise exec -- <bin>` gets a bare ENOENT; running a one-off `mise x -- prettier` on a machine where no config provides prettier; a package upgrade renamed its bin.
Related errors
- brew is not available: {}
- {bin_name} is not a mise bin. Perhaps you need to install it
- recursive shim invocation detected for {bin_name}: {}
- no supported firewall backend found (tried nft, firewall-cmd
- firewall backend '{}' requires command '{}'
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/1844f678c41b5c75.
Report an issue: GitHub.