{"record":{"id":"9a5033eacdee72f7","repo":"jdx/mise","slug":"brew-cask-completion-target-already-exists-a","errorCode":null,"errorMessage":"brew-cask: completion target '{}' already exists and is not owned by cask '{}'","messagePattern":"brew-cask: completion target '(.+?)' already exists and is not owned by cask '(.+?)'","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/packages/brew/cask.rs","lineNumber":4146,"sourceCode":"    }\n    if let Some(parent) = target.parent() {\n        create_dir_all_elevating(parent)?;\n    }\n    ensure_completion_target_replaceable(cask, artifacts, target)?;\n    make_symlink_elevating(&caskroom_completion, target)?;\n    Ok(())\n}\n\nfn ensure_completion_target_replaceable(\n    cask: &Cask,\n    artifacts: &CaskArtifacts,\n    target: &Path,\n) -> Result<()> {\n    let Ok(metadata) = target.symlink_metadata() else {\n        return Ok(());\n    };\n    if !metadata.file_type().is_symlink() {\n        bail!(\n            \"brew-cask: completion target '{}' already exists and is not owned by cask '{}'\",\n            target.display(),\n            cask.token\n        );\n    }\n    let link_target = std::fs::read_link(target)?;\n    let resolved = resolve_symlink_target(target, link_target);\n    let token_dir = caskroom_token_dir(&cask.token);\n    if path_starts_with_resolved_root(&resolved, &token_dir) {\n        return Ok(());\n    }\n    for completion in &artifacts.completions {\n        if completion.target_path()? != target {\n            continue;\n        }\n        if let Some(source) = appdir_artifact_source(&completion.source, &artifacts.apps)?\n            && file::same_file(&resolved, &source)\n        {","sourceCodeStart":4128,"sourceCodeEnd":4164,"githubUrl":"https://github.com/jdx/mise/blob/6f52dcdf99e282ef7a7db68c81301fa4618d0f79/src/system/packages/brew/cask.rs#L4128-L4164","documentation":"The completion link target already exists and is not a symlink (a regular file or directory). A completion target may only be replaced when it is a symlink whose ownership this cask can prove; a foreign real file is never clobbered, so the install aborts with the cask token in the message.","triggerScenarios":"A user dotfiles setup or another package copied a real completion file to the target path; the target path exists as a directory rather than a link.","commonSituations":"Dotfiles repositories that `cp` completions into place; a distro or other package manager installing the same completion name; README instructions telling users to copy the completion file manually.","solutions":["Delete or rename the non-symlink file at the completion target after confirming it is not needed","Change the completion artifact's target to a cask-unique file name","Adjust user setup scripts to symlink rather than copy completions so ownership checks pass"],"exampleFix":"# shell - resolve the foreign regular file before reinstalling\nls -l ~/.zsh/completions/_myapp   # regular file, not a symlink\nmv ~/.zsh/completions/_myapp ~/.zsh/completions/_myapp.bak","handlingStrategy":"validation","validationCode":"// Only proceed when the completion target is absent or a symlink we may own\nmatch target.symlink_metadata() {\n    Err(_) => Ok(()),\n    Ok(m) if m.file_type().is_symlink() => Ok(()),\n    Ok(_) => Err(eyre!(\"completion target '{}' is a real file/dir; move it aside first\", target.display())),\n}","typeGuard":null,"tryCatchPattern":"if err.to_string().contains(\"completion target\") && err.to_string().contains(\"is not owned by cask\") {\n    // surface the path and the cask token so the user can relocate the foreign file\n}","preventionTips":["Never copy completion files into shared completion directories; symlink them","Check the target path with ls -l before installing a cask that links completions","Namespace completion target names by tool to avoid collisions"],"tags":["brew-cask","completion","conflict","ownership"],"backgroundTag":"package-ownership-conflict","analyzedSha":"6f52dcdf99e282ef7a7db68c81301fa4618d0f79","analyzedAt":"2026-08-22T10:14:23.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}