{"record":{"id":"aa8b7be955bfc246","repo":"jdx/mise","slug":"brew-cask-invalid-completion-target-target-name-aa8b7b","errorCode":null,"errorMessage":"brew-cask: invalid completion target '{target_name}'","messagePattern":"brew-cask: invalid completion target '(.+?)'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/packages/brew/cask/mod.rs","lineNumber":3238,"sourceCode":"            }\n        }\n        CompletionShell::Zsh => {\n            if filename.starts_with('_') {\n                filename.to_string()\n            } else {\n                format!(\"_{stem}\")\n            }\n        }\n        CompletionShell::Pwsh => {\n            if filename.ends_with(\".ps1\") {\n                filename.to_string()\n            } else {\n                format!(\"{stem}.ps1\")\n            }\n        }\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        );","sourceCodeStart":3220,"sourceCodeEnd":3256,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/packages/brew/cask/mod.rs#L3220-L3256","documentation":"This error is thrown by completion_filename when, after normalizing a bare (no-slash) completion target name for the target shell, the resulting filename is empty. That means the caller passed an empty or stem-less target name (e.g. \"\", \".fish\", \".ps1\", or just \"_\") so no valid completion file name can be derived.","triggerScenarios":"A cask completion entry with a bare target_name that is empty, or reduces to an empty stem after stripping extension/underscore normalization (e.g. target \".fish\" for fish, \".ps1\" for pwsh, \"_\" handling edge cases), triggering the normalized.is_empty() bail.","commonSituations":"A hand-edited cask with an empty completions target string; a templated cask where a name variable expanded to nothing; a target given as only a file extension; programmatic generation of cask manifests leaving the completion target blank.","solutions":["Set the completion target to the tool's actual name (e.g. \"mytool\"), letting the shell-specific suffix/underscore be added automatically.","Remove the empty completion entry from the cask if the cask ships no completions.","Fix the template or variable that produced an empty name before it reaches the manifest.","Validate cask manifests (target non-empty and non-extension-only) before installing."],"exampleFix":"// before\ncompletions = [{ target = \"\" }]\n// after\ncompletions = [{ target = \"mytool\" }]","handlingStrategy":"validation","validationCode":"fn valid_bare_target(name: &str) -> bool {\n    let stem = std::path::Path::new(name).file_stem().and_then(|s| s.to_str()).unwrap_or(\"\");\n    !name.trim().is_empty() && !stem.trim().is_empty()\n}\n// reject the completion entry when !valid_bare_target(target)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Require a non-empty, non-extension-only tool name in every completions entry.","Add schema validation (non-empty string, no path separators) for bare target names in cask manifests.","Fail fast in CI when generated cask manifests contain empty target fields."],"tags":["validation","brew-cask","completions","empty-value"],"backgroundTag":"empty-required-field","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"}