jdx/mise · error

has no executable called

Error message

{} has no executable called {program}

What it means

run_tool, which executes a tool's own binary to capture output for packslip completions, asked the backend's `which` for the named program and got nothing. The installed tool version does not expose an executable with that name, so the exec entry cannot run.

Solutions

  1. Check the binary name inside the installed tool version (ls the install path / tool's bin dir)
  2. Update the exec entry to the correct executable name
  3. Pin/use a tool version that actually contains the referenced binary
  4. Ensure the platform you run on ships that executable

Example fix

// before
// exec = ["mytool-cli", "completions"]
// after
// exec = ["mytool", "completions"]  # actual binary name in the installed version
Defensive patterns

Strategy: validation

Validate before calling

const which = await backend.which(config, tv, program);
if (!which) throw new Error(`${tv} has no executable ${program}`);

Try / catch

try { await runTool(...) } catch (e) { if (/has no executable called/.test(e.message)) { correctBinaryName(); } else { throw e; } }

Prevention

When it happens

Trigger: The exec entry names a program (e.g. "mytool" or a helper binary) that does not exist in the installed tool version — wrong binary name, renamed binary in a newer version, or the packslip targets a tool variant without that executable.

Common situations: Upstream renamed the binary between versions, packslip written for a different tool layout, typo in the executable name, completions entry referencing a binary only present on some platforms.

Related errors


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

Appendix: source

Thrown at src/packslip.rs:1361

    match by_name {
        Some(found) => Ok(found),
        None => bail!("{name} is not an active, installed tool or one of their executables"),
    }
}

/// Run one of the tool's own executables and return what it printed.
async fn run_tool(
    config: &Arc<Config>,
    backend: &Arc<dyn Backend>,
    tv: &ToolVersion,
    argv: &[String],
    env: &BTreeMap<String, String>,
) -> Result<String> {
    let Some((program, args)) = argv.split_first() else {
        bail!("an exec entry with no command");
    };
    let Some(path) = backend.which(config, tv, program).await? else {
        bail!("{} has no executable called {program}", tv.style());
    };
    run_resource_command(
        &path,
        args,
        env,
        &tv.install_path(),
        std::time::Duration::from_secs(5),
    )
    .await
}

/// Run vendor resource generation outside the user's project, without
/// input, under a deadline. Empty output is a failed source, never a cache hit.
async fn run_resource_command(
    path: &Path,
    args: &[String],
    env: &BTreeMap<String, String>,
    install_path: &Path,

View on GitHub (pinned to 533346cc37)