jdx/mise · error
brew-cask: {kind} '{name}' is ambiguous: {}
Error message
brew-cask: {kind} '{name}' is ambiguous: {} What it means
Cask artifact globs can match multiple staged files. `single_match` is mise's disambiguation helper: it accepts exactly zero or one match and throws this error when more than one path matches, listing all candidates. The cask definition is then too vague for mise to know which artifact to link.
Source
Thrown at src/system/packages/brew/cask/mod.rs:2820
continue;
}
let path = target.join(&suffix);
if path.is_file() {
matches.push(path);
}
}
matches.sort();
matches.dedup();
single_match(&matches, "APPDIR artifact", source)
}
/// `kind` and `name` build the ambiguity error, e.g. "brew-cask: APPDIR
/// artifact 'x' is ambiguous: a, b".
fn single_match(matches: &[PathBuf], kind: &str, name: &str) -> Result<Option<PathBuf>> {
match matches {
[] => Ok(None),
[path] => Ok(Some(path.clone())),
_ => bail!(
"brew-cask: {kind} '{name}' is ambiguous: {}",
matches
.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);
single_match(&matches, "completion executable", executable)View on GitHub (pinned to afd2eddd3a)
Solutions
- Inspect the candidate list in the message and tighten the cask's artifact glob to match exactly one path
- Pin the artifact name to the specific file you want instead of a wildcard
- Update the cask definition after upstream restructures its payload
- Report the cask to its maintainer if the upstream change made the pattern ambiguous
Example fix
// before (cask stanza) app "*/*.app" // after app "MyTool.app"
Defensive patterns
Strategy: validation
Validate before calling
# preview the glob before installing count=$(find <stage-dir> -path '<glob>' | wc -l); [ "$count" -le 1 ] || echo "ambiguous: $count matches"
Try / catch
match result {
Err(e) if e.contains("is ambiguous") => {
let candidates = e.split(": ").last();
eprintln!("tighten the cask artifact glob to one of: {candidates:?}");
}
Err(e) => return Err(e),
Ok(v) => v,
} Prevention
- Prefer exact artifact names over wildcards in cask definitions
- Re-check globs after upstream restructures its payload
- Dry-run/list the staged files when authoring a cask
When it happens
Trigger: A helper resolving an artifact by glob (e.g. APPDIR artifacts, as the doc comment shows) receives a `matches` slice with 2+ PathBufs and calls `bail!` with the joined candidate list.
Common situations: A cask glob like `*.app` or `bin/*` matches several staged entries after an upstream release added new files; a too-broad wildcard in a custom cask; upstream restructured its payload so a previously unique match is now duplicated.
Related errors
- brew-cask: structured move with multiple sources requires a
- brew-cask: structured copy source must resolve to exactly on
- brew-cask: structured symlink source '{}' did not match any
- brew-cask: structured symlink globs must use staged_path
- brew-cask: structured flight glob '{}' matched outside stage
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/c7e53d678a0d5c2c.
Report an issue: GitHub.