jdx/mise · error
brew-cask: invalid completion target '{}'
Error message
brew-cask: invalid completion target '{}' What it means
caskroom_completion_path maps a validated completion target into the cask's private caskroom by stripping the brew prefix from it. If stripping leaves an empty relative path — i.e. the resolved target is exactly the brew prefix itself — there is no file component to relocate and mise bails. It is the degenerate-target guard between the strip_prefix containment check and the final caskroom.join.
Source
Thrown at src/system/packages/brew/cask.rs:4510
}
};
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 completion_target_paths(cask: &Cask, artifacts: &CaskArtifacts) -> Result<Vec<PathBuf>> {
let mut targets = artifacts
.completions
.iter()
.map(CompletionArtifact::target_path)
.collect::<Result<Vec<_>>>()?;
for generated in &artifacts.generated_completions {
targets.extend(generated.target_paths(cask)?);
}
targets.sort();
targets.dedup();View on GitHub (pinned to 6f52dcdf99)
Solutions
- Point the completion target at a concrete file under the prefix, e.g. 'share/zsh/site-functions/_tool', not a directory or the prefix itself.
- Check how the target value was produced — a leading variable that expanded to empty often yields the bare prefix.
- Add an authoring-time lint: target must contain at least one path component below the prefix.
Example fix
# before — target resolves to the prefix itself "target": "/opt/homebrew" # after "target": "/opt/homebrew/share/zsh/site-functions/_tool"
Defensive patterns
Strategy: validation
Validate before calling
# target must have at least one component below the brew prefix PREFIX="$(brew --prefix)" case "$TARGET" in "$PREFIX"|"$PREFIX/") echo 'target is the prefix itself'; exit 1;; esac
Prevention
- Always author completion targets as concrete file paths, never directories or roots.
- When templating target paths, assert the rendered value differs from the prefix.
- Prefer relative targets so mise derives the location itself.
When it happens
Trigger: A completion target that resolves to the brew prefix root: an absolute target equal to the prefix (e.g. '/opt/homebrew'), or one that normalizes to it. `relative.components().next().is_none()` at src/system/packages/brew/cask.rs:4510 is true only when strip_prefix consumed the entire path.
Common situations: Cask metadata where the target field accidentally holds the prefix or '/' after templating; hand-written stanzas that pasted a directory instead of a file path; programmatic cask generation that emits the install root when a variable is empty.
Related errors
- brew-cask: completion executable '{}' is ambiguous: {}
- brew-cask: failed to generate {} completions from {}: {}
- brew-cask: completion target '{}' must not contain '..'
- brew-cask: invalid completion target '{target_name}'
- brew-cask: invalid binary target '{}'
AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22).
Data as JSON: /api/errors/619e49b7f7290b7b.
Report an issue: GitHub.