jdx/mise · error

brew-cask: completion target '{}' already points to '{}' and

Error message

brew-cask: completion target '{}' already points to '{}' and is not owned by cask '{}'

What it means

The completion target is a symlink, but it does not belong to this cask: the link resolves outside this cask's caskroom token directory, and it does not point (same-file) at any completion source declared in this cask's artifacts. The installer refuses to retarget a link owned by another origin.

Source

Thrown at src/system/packages/brew/cask.rs:4168

        );
    }
    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 6f52dcdf99)

Solutions

  1. Uninstall the other cask (or remove its link) that owns the completion target
  2. Retarget this cask's completion artifact to a unique file name, for example prefixed with the token
  3. If the existing link is one you created yourself, delete it and let the cask recreate it

Example fix

# shell - inspect and clear the foreign link
readlink ~/.zsh/completions/_myapp   # points outside this cask's caskroom
rm ~/.zsh/completions/_myapp
Defensive patterns

Strategy: validation

Validate before calling

// Before install, verify an existing completion link belongs to this cask
if let Ok(m) = target.symlink_metadata() && m.file_type().is_symlink() {
    let resolved = resolve_symlink_target(&target, std::fs::read_link(&target)?);
    if !path_starts_with_resolved_root(&resolved, &caskroom_token_dir(&cask.token)) {
        return Err(eyre!("completion target '{}' owned by another origin", target.display()));
    }
}

Try / catch

if err.to_string().contains("already points to") && err.to_string().contains("not owned by cask") {
    // the message names the current link target; uninstall the other owner or remove the link
}

Prevention

When it happens

Trigger: A different cask (different token) already links a completion with the same file name; the user symlinked the completion to a locally built copy; two casks declaring colliding completion target names.

Common situations: Stable and dev casks of the same tool both installing completions; a user-managed completions directory; the completion target path changed between cask versions leaving an old link behind.

Related errors


AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22). Data as JSON: /api/errors/5a9b12b937c6ab1c. Report an issue: GitHub.