{"record":{"id":"e2998b339b3288a2","repo":"jdx/mise","slug":"brew-cask-invalid-completion-target-e2998b","errorCode":null,"errorMessage":"brew-cask: invalid completion target '{}'","messagePattern":"brew-cask: invalid completion target '(.+?)'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/packages/brew/cask/mod.rs","lineNumber":3253,"sourceCode":"        }\n    };\n    if normalized.is_empty() {\n        bail!(\"brew-cask: invalid completion target '{target_name}'\");\n    }\n    Ok(normalized)\n}\n\nfn caskroom_completion_path(caskroom: &Path, target: &Path) -> Result<PathBuf> {\n    let prefix = prefix::prefix();\n    let relative = target.strip_prefix(&prefix).map_err(|_| {\n        eyre!(\n            \"brew-cask: completion target '{}' must be under {}\",\n            target.display(),\n            prefix.display()\n        )\n    })?;\n    if relative.components().next().is_none() {\n        bail!(\n            \"brew-cask: invalid completion target '{}'\",\n            target.display()\n        );\n    }\n    Ok(caskroom.join(relative))\n}\n\nfn previous_completion_targets(cask: &Cask) -> Result<Vec<PathBuf>> {\n    Ok(previous_receipt(cask)?\n        .map(|receipt| receipt.completions)\n        .unwrap_or_default())\n}\n\nfn remove_obsolete_completions(\n    cask: &Cask,\n    previous_targets: &[PathBuf],\n    current_targets: &[PathBuf],\n) -> Result<()> {","sourceCodeStart":3235,"sourceCodeEnd":3271,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/packages/brew/cask/mod.rs#L3235-L3271","documentation":"This error is thrown by caskroom_completion_path when a validated completion target, after being stripped of the Homebrew prefix, has no remaining components — i.e. the target equals the prefix directory itself rather than a file inside it. Since there would be no relative path to mirror into the caskroom, the operation is rejected.","triggerScenarios":"A cask completion target that resolves exactly to the Homebrew prefix root (e.g. target_name \"\" or \".\" combined with prefix joining, or $HOMEBREW_PREFIX alone), so target.strip_prefix(prefix) yields an empty relative path and relative.components().next() is None.","commonSituations":"A cask whose completion target is set to just the $HOMEBREW_PREFIX placeholder or \".\"; a mis-templated manifest where the file-name portion of the target is dropped; programmatically assembled paths that end up as the prefix itself.","solutions":["Give the completion target an actual file name under the prefix (e.g. $HOMEBREW_PREFIX/etc/bash_completion.d/mytool).","Remove the degenerate completion entry pointing at the prefix root.","Fix the manifest/template so the file-name segment is not lost when building the target path.","Log/inspect the resolved target path to confirm it names a file, not the prefix directory."],"exampleFix":"// before\ncompletions = [{ target = \"$HOMEBREW_PREFIX\" }]\n// after\ncompletions = [{ target = \"$HOMEBREW_PREFIX/share/zsh/site-functions/_mytool\" }]","handlingStrategy":"validation","validationCode":"let relative = target.strip_prefix(&prefix).map_err(|_| \"target outside prefix\")?;\nif relative.as_os_str().is_empty() || relative.components().next().is_none() {\n    return Err(\"target must name a file under the prefix, not the prefix itself\".into());\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure completion targets always include a file-name component beneath $HOMEBREW_PREFIX.","Reject targets that normalize to the prefix root ('' or '.') during manifest validation.","When building targets programmatically, assert the joined path is strictly deeper than the prefix."],"tags":["validation","brew-cask","completions","path-resolution"],"backgroundTag":"invalid-argument-value","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}