jdx/mise · error
brew-cask: completion target
Error message
brew-cask: completion target '{}' already points to '{}' and is not owned by cask '{}' What it means
For an existing symlink at a cask completion target, mise resolves it and checks ownership: the link must point at the staged caskroom artifact (or, for appdir artifacts, a file identical to the matching staged app source). If the resolved link points elsewhere, the target is owned by another installation (or a stale link), so mise bails instead of repointing a link it doesn't own.
Solutions
- Remove the foreign/stale symlink at the target path and retry the cask install.
- Identify what created the link (brew cask, other tool) and uninstall that owner first.
- If the link points at a deleted old version, it is stale — delete it and reinstall.
- If two tools legitimately conflict, choose one or adjust the completion target in configuration.
Example fix
// before: symlink owned by another install readlink /usr/local/bin/mytool # /opt/homebrew/Caskroom/other/1.0/bin/mytool // after: remove the foreign link and reinstall rm /usr/local/bin/mytool && mise install cask://my-tool
Defensive patterns
Strategy: validation
Validate before calling
use std::path::Path;
fn link_owned_by_cask(target: &Path, caskroom_prefix: &str) -> bool {
target
.read_link()
.ok()
.map(|l| l.to_string_lossy().contains(caskroom_prefix))
.unwrap_or(false)
} Type guard
fn is_symlink(target: &std::path::Path) -> bool {
target
.symlink_metadata()
.map(|md| md.file_type().is_symlink())
.unwrap_or(false)
} Try / catch
// Rust
match install_cask_completion(&cask, &artifacts, &caskroom, &target) {
Err(e) if e.to_string().contains("already points to") => {
// inspect readlink(target); remove stale/foreign link, then retry once
}
other => other,
} Prevention
- Keep symlink ownership per package: never share one bin path across brew cask and mise cask.
- Clean up symlinks after uninstalling the previous manager for a tool.
- Watch for stale links to deleted cask versions and remove them.
- Resolve existing links with readlink before installing to detect conflicts early.
When it happens
Trigger: Installing a cask whose completion target already is a symlink, but read_link/resolution shows it points to a path that is not this cask's staged artifact, and it is not same_file to the matching appdir artifact source for cask.token.
Common situations: A symlink created by native Homebrew or another version manager points at its own Cellar/Caskroom; a stale symlink survives after the old cask version was deleted; two casks or tools claim the same binary name (e.g. two CLI tools installing the same shim path).
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- brew-cask: cannot adopt
- brew-cask: completion target
- brew-cask: completion target
- brew-cask: : conflicts with installed cask
- brew-cask: : Homebrew owns this cask; remove it with…
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/46d9b5098cb90dff.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/packages/brew/cask/mod.rs:2927
);
}
let link_target = std::fs::read_link(target)?;
let resolved = resolve_symlink_target(target, link_target);
let token_dir = caskroom_token_dir(&cask.token);
if path_starts_with_resolved_root(&resolved, &token_dir) {
return Ok(());
}
for completion in &artifacts.completions {
if completion.target_path()? != target {
continue;
}
if let Some(source) = appdir_artifact_source(&completion.source, &artifacts.apps)?
&& file::same_file(&resolved, &source)
{
return Ok(());
}
}
bail!(
"brew-cask: completion target '{}' already points to '{}' and is not owned by cask '{}'",
target.display(),
resolved.display(),
cask.token
)
}
fn find_completion_source(
stage: &Path,
caskroom: &Path,
cask: &Cask,
apps: &[AppArtifact],
source: &str,
) -> Result<Option<PathBuf>> {
for root in [caskroom, stage] {
if let Some(source) = generated_caskroom_artifact(root, cask, source)
&& source.is_file()
{View on GitHub (pinned to 533346cc37)