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

If the completion target already exists as a symlink, mise checks whether it points to (or resolves through, or matches via same_file) something owned by this cask — e.g. the cask's staged completion or an AppDir artifact. If the resolved path belongs to something else, this error is thrown, reporting both what the link currently points to and the owning cask token, preventing silent repointing of a foreign symlink.

Source

Thrown at src/system/packages/brew/cask/mod.rs:2710

        );
    }
    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 afd2eddd3a)

Solutions

  1. Inspect `readlink` on the target to see what it points to and decide if that source is still wanted
  2. Remove the stale/foreign symlink and re-run the cask install so mise creates its own link
  3. If the link should be owned by another cask, remove that cask first or adjust its completion target
  4. Update mise if a layout migration left pre-upgrade links unclaimed

Example fix

// before: symlink points at old Homebrew path
rm ~/.zsh/completions/_mytool
mise install <cask>
// after: mise-owned symlink to the staged completion
Defensive patterns

Strategy: try-catch

Validate before calling

readlink <target-path>   # confirm the symlink points at this cask's staged file

Try / catch

match result {
  Err(e) if e.contains("already points to") && e.contains("not owned by cask") => {
    eprintln!("foreign symlink at target; remove it or repoint the other cask, then reinstall: {e}");
  }
  Err(e) => return Err(e),
  Ok(v) => v,
}

Prevention

When it happens

Trigger: The target is a symlink whose `read_link`-resolved path fails all ownership checks: it doesn't match this cask's expected completion source and `file::same_file(&resolved, &source)` is false for every candidate AppDir source.

Common situations: The symlink was created by a different cask, an older mise layout, or Homebrew, and still points at an uninstalled or relocated binary; the user hand-created a symlink at the completion 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


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/46d9b5098cb90dff. Report an issue: GitHub.