jdx/mise · error
brew-cask: completion target '{}' already exists and is not
Error message
brew-cask: completion target '{}' already exists and is not owned by cask '{}' What it means
When linking a completion artifact, mise refuses to overwrite an existing completion path unless it is a symlink (i.e., previously managed by mise or pointing into the cask). If a real file or directory already occupies the target, this error is thrown to avoid clobbering data mise does not own, identified by the cask token.
Source
Thrown at src/system/packages/brew/cask/mod.rs:2688
}
if let Some(parent) = target.parent() {
create_dir_all_elevating(parent)?;
}
ensure_completion_target_replaceable(cask, artifacts, target)?;
make_symlink_elevating(&caskroom_completion, target)?;
Ok(())
}
fn ensure_completion_target_replaceable(
cask: &Cask,
artifacts: &CaskArtifacts,
target: &Path,
) -> Result<()> {
let Ok(metadata) = target.symlink_metadata() else {
return Ok(());
};
if !metadata.file_type().is_symlink() {
bail!(
"brew-cask: completion target '{}' already exists and is not owned by cask '{}'",
target.display(),
cask.token
);
}
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)
{View on GitHub (pinned to afd2eddd3a)
Solutions
- Inspect the existing file at the target path and back it up if you want to keep it
- Remove or rename the conflicting file/directory and re-run the install
- Verify the existing completion isn't owned by another tool (e.g. a system package) before deleting
- If another tool owns it, configure mise/the cask to use a different completion target
Example fix
// before: real file blocks the link mv ~/.zsh/completions/_mytool ~/.zsh/completions/_mytool.bak // after: install creates a mise-owned symlink mise install <cask>
Defensive patterns
Strategy: try-catch
Validate before calling
p=<target-path>; if [ -e "$p" ] && [ ! -L "$p" ]; then echo "non-symlink exists at $p — will conflict"; fi
Try / catch
match result {
Err(e) if e.contains("already exists and is not owned by cask") => {
eprintln!("back up and remove the existing non-symlink at the target, then reinstall: {e}");
}
Err(e) => return Err(e),
Ok(v) => v,
} Prevention
- Check completion target paths for pre-existing files before installing a cask
- Avoid mixing Homebrew/manual completion installs with mise-managed ones at the same paths
- Keep one owner per completion path
When it happens
Trigger: `target.symlink_metadata()` succeeds and `!metadata.file_type().is_symlink()` — a regular file, directory, or other non-symlink already exists at the completion target path before this cask is linked.
Common situations: The user (or Homebrew previously) installed a real completion file at the same path; another package manager owns the completion; a previous non-symlink install left files behind.
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: completion target '{}' already points to '{}' and
- brew-cask: staged symlink path escaped extraction root: {}
- brew-cask: refusing generic artifact source outside the extr
- brew-cask: refusing to restore flight target through a chang
- brew-cask: structured symlink source '{}' did not match any
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/3b9b440507288c03.
Report an issue: GitHub.