jdx/mise · error

brew-cask: completion executable '{}' is ambiguous: {}

Error message

brew-cask: completion executable '{}' is ambiguous: {}

What it means

While resolving the executable for a cask's generated-completion stanza, mise first tries the direct path under the staged caskroom, then falls back to find_file_artifacts, which walks the staged tree and matches any file whose relative path ends with the given name. If more than one file matches, mise cannot know which binary to run for completion generation and aborts. This is a deterministic disambiguation guard, not a flaky filesystem issue.

Source

Thrown at src/system/packages/brew/cask.rs:4300

                .iter()
                .map(|path| path.display().to_string())
                .collect::<Vec<_>>()
                .join(", ")
        ),
    }
}

fn find_generated_completion_file(root: &Path, executable: &str) -> Result<Option<PathBuf>> {
    let executable_path = Path::new(executable);
    let direct = root.join(executable_path);
    if direct.is_file() {
        return Ok(Some(direct));
    }
    let matches = find_file_artifacts(root, executable_path);
    match matches.as_slice() {
        [] => Ok(None),
        [path] => Ok(Some(path.clone())),
        _ => bail!(
            "brew-cask: completion executable '{}' is ambiguous: {}",
            executable,
            matches
                .iter()
                .map(|path| path.display().to_string())
                .collect::<Vec<_>>()
                .join(", ")
        ),
    }
}

fn find_file_artifacts(root: &Path, name: &Path) -> Vec<PathBuf> {
    let mut matches = WalkDir::new(root)
        .into_iter()
        .filter_entry(|entry| entry.file_name() != "__MACOSX")
        .filter_map(|entry| entry.ok())
        .map(|entry| entry.into_path())
        .filter(|path| {

View on GitHub (pinned to 6f52dcdf99)

Solutions

  1. In the cask's generated-completion stanza, give the executable as an unambiguous relative path (e.g. "bin/pulumi" instead of "pulumi") so the direct root.join() hit at the top of find_generated_completion_file succeeds.
  2. Inspect the staged caskroom payload (the cask's staged directory under the brew prefix) for duplicate matching filenames: the error message lists every candidate path; pick the correct one and use its path relative to the stage root.
  3. If you maintain the cask definition, point the stanza at the exact binary that implements completion generation, and add a test that only one candidate exists.
  4. If you cannot change the stanza, update mise — a newer revision may add precedence rules — or disable the generated-completion stanza for that cask.

Example fix

# cask generated-completion stanza (before)
"completions": { "generated": [{ "executable": "pulumi", "shell": "zsh" }] }
# ambiguous: bin/pulumi and libexec/pulumi/pulumi both match

# after — disambiguate with the relative path
"completions": { "generated": [{ "executable": "bin/pulumi", "shell": "zsh" }] }
Defensive patterns

Strategy: validation

Validate before calling

# before mise install, check the staged payload for duplicate matches
EXE="pulumi"; ROOT="$(mise where brew-cask:<token> 2>/dev/null || echo /dev/null)"
if [ -d "$ROOT" ]; then
  COUNT=$(find "$ROOT" -type f -path "*$EXE" ! -path "*__MACOSX*" | wc -l)
  [ "$COUNT" -gt 1 ] && echo "ambiguous: pick an exact relative path" && find "$ROOT" -type f -path "*$EXE"
fi

Prevention

When it happens

Trigger: A cask declares a generated completion whose 'executable' is a bare name (e.g. "pulumi") and the staged payload contains multiple files whose relative paths end with that name, e.g. both 'bin/pulumi' and 'libexec/pulumi/pulumi' (find_file_artifacts matches relative.ends_with(name) at src/system/packages/brew/cask.rs:4320). It only fires when the direct join root/executable is not itself a file.

Common situations: Apps that ship a launcher script plus a same-named real binary in a nested directory; wrapper-and-target layouts common in Go/Rust CLIs; cask stanzas written against an older payload layout that later added a second copy of the binary; __MACOSX entries are already filtered, so remaining duplicates are real payload files.

Related errors


AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22). Data as JSON: /api/errors/0cc11bb4bd1d28ec. Report an issue: GitHub.