jdx/mise · error

--install takes the executable's name, not a tool id; run `m

Error message

--install takes the executable's name, not a tool id; run `mise completion {} --tool {tool}` to see what the id resolves to

What it means

When installing a completion stub via `mise completion <shell> --install`, the `--tool`/positional value must be a plain executable name (e.g. `node`), because the stub is filed under and completes that name. Passing a tool id such as `github.com/owner/repo` or `aqua:foo/bar` is rejected; mise hints that `--tool` resolution should be inspected separately.

Source

Thrown at src/cli/completion.rs:171

            return self.install_script(shell.into());
        }
        let script = Cli::completion_script(shell.into());
        miseprintln!("{}", script.trim());

        Ok(())
    }

    /// Put a stub for a tool where this shell looks for its completion. The stub defers to
    /// `mise completion <shell> --tool <tool>` at completion time, so the script always matches
    /// the version that is active, and the file never needs rewriting on a version switch.
    fn install_tool_stub(&self, tool: &str, shell: usage_rs::complete::Shell) -> Result<()> {
        use usage_rs::install::{self, OnForeign};

        // The stub is filed under the command's name and completes that
        // name, so it must be the executable as typed, not a tool id such
        // as github.com/owner/repo.
        if !crate::file::is_plain_file_name(tool) {
            eyre::bail!(
                "--install takes the executable's name, not a tool id; run `mise completion {} --tool {tool}` to see what the id resolves to",
                shell.as_str()
            );
        }
        let stub = crate::packslip::stub(tool, shell)?;
        let on_foreign = if self.force {
            OnForeign::Overwrite
        } else {
            OnForeign::Refuse
        };
        let plan = install::plan_for("mise", tool, shell, &install::Env::from_process())
            .map_err(eyre::Report::new)?;
        let done = install::write(&plan, &stub, on_foreign).map_err(|err| match &err {
            install::Error::Foreign { .. } => eyre::eyre!(
                "{err}\n\nPass --force to replace it, or redirect `mise completion {} --tool {tool}` yourself.",
                shell.as_str()
            ),
            _ => eyre::Report::new(err),

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Pass the plain executable name, e.g. `mise completion bash --install rg`
  2. If unsure what executable a tool id provides, run `mise completion <shell> --tool <id>` to resolve it first
  3. Install the tool first (`mise use <tool-id>`) so the executable name is known, then install the stub by that name

Example fix

// before
mise completion bash --install github.com/BurntSushi/ripgrep
// after
mise completion bash --install rg
Defensive patterns

Strategy: validation

Validate before calling

const isPlainFileName = s => !s.includes('/') && !s.includes(':');
if (!isPlainFileName(tool)) throw new Error(`use executable name, not ${tool}`);

Type guard

const isPlainFileName = (s) => typeof s === 'string' && /^[\w.-]+$/.test(s);

Prevention

When it happens

Trigger: `mise completion <shell> --install github.com/owner/repo` or `--tool aqua:owner/repo`, i.e. passing a backend-qualified tool id instead of the executable's file name; copying a tool id from `mise ls` into the completion command.

Common situations: Confusing tool installation ids with executable names for multi-binary tools (e.g. installing completions for `rg` whose tool id is `ubi:BurntSushi/ripgrep`); scripting completion install from a tool list.

Understand the failure class

Background: "Unknown argument", "Invalid value", and "must be one of": invalid CLI argument errors explained — this error's family across 35 libraries.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/51956fe0330c046e. Report an issue: GitHub.