jdx/mise · error
brew-cask: invalid completion target
Error message
brew-cask: invalid completion target '{}' What it means
This error is thrown by caskroom_completion_path when a validated completion target, after being stripped of the Homebrew prefix, has no remaining components — i.e. the target equals the prefix directory itself rather than a file inside it. Since there would be no relative path to mirror into the caskroom, the operation is rejected.
Solutions
- Give the completion target an actual file name under the prefix (e.g. $HOMEBREW_PREFIX/etc/bash_completion.d/mytool).
- Remove the degenerate completion entry pointing at the prefix root.
- Fix the manifest/template so the file-name segment is not lost when building the target path.
- Log/inspect the resolved target path to confirm it names a file, not the prefix directory.
Example fix
// before
completions = [{ target = "$HOMEBREW_PREFIX" }]
// after
completions = [{ target = "$HOMEBREW_PREFIX/share/zsh/site-functions/_mytool" }] Defensive patterns
Strategy: validation
Validate before calling
let relative = target.strip_prefix(&prefix).map_err(|_| "target outside prefix")?;
if relative.as_os_str().is_empty() || relative.components().next().is_none() {
return Err("target must name a file under the prefix, not the prefix itself".into());
} Prevention
- Ensure completion targets always include a file-name component beneath $HOMEBREW_PREFIX.
- Reject targets that normalize to the prefix root ('' or '.') during manifest validation.
- When building targets programmatically, assert the joined path is strictly deeper than the prefix.
When it happens
Trigger: A cask completion target that resolves exactly to the Homebrew prefix root (e.g. target_name "" or "." combined with prefix joining, or $HOMEBREW_PREFIX alone), so target.strip_prefix(prefix) yields an empty relative path and relative.components().next() is None.
Common situations: A cask whose completion target is set to just the $HOMEBREW_PREFIX placeholder or "."; a mis-templated manifest where the file-name portion of the target is dropped; programmatically assembled paths that end up as the prefix itself.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- brew-cask: invalid completion target
- brew-cask: completion executable
- brew-cask: completion target
- brew-cask: completion target
- brew-cask: completion target
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/e2998b339b3288a2.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/packages/brew/cask/mod.rs:3253
}
};
if normalized.is_empty() {
bail!("brew-cask: invalid completion target '{target_name}'");
}
Ok(normalized)
}
fn caskroom_completion_path(caskroom: &Path, target: &Path) -> Result<PathBuf> {
let prefix = prefix::prefix();
let relative = target.strip_prefix(&prefix).map_err(|_| {
eyre!(
"brew-cask: completion target '{}' must be under {}",
target.display(),
prefix.display()
)
})?;
if relative.components().next().is_none() {
bail!(
"brew-cask: invalid completion target '{}'",
target.display()
);
}
Ok(caskroom.join(relative))
}
fn previous_completion_targets(cask: &Cask) -> Result<Vec<PathBuf>> {
Ok(previous_receipt(cask)?
.map(|receipt| receipt.completions)
.unwrap_or_default())
}
fn remove_obsolete_completions(
cask: &Cask,
previous_targets: &[PathBuf],
current_targets: &[PathBuf],
) -> Result<()> {View on GitHub (pinned to 533346cc37)