jdx/mise · error
brew-cask: command_wrapper requires a command name without p
Error message
brew-cask: command_wrapper requires a command name without path components
What it means
This error is thrown by parse_command_wrapper_artifact when a Homebrew cask `command_wrapper` artifact declares a command name that contains path components (e.g. 'bin/tool' or './tool'). The library requires a bare executable name so the wrapper can be installed under a single file name in the command directory.
Source
Thrown at src/system/packages/brew/cask/artifacts.rs:191
pub(super) fn parse_command_wrapper_artifact(
value: &Value,
) -> Result<Option<CommandWrapperArtifact>> {
let Some(wrapper) = value.as_object().and_then(|o| o.get("command_wrapper")) else {
return Ok(None);
};
let values = wrapper
.as_array()
.ok_or_else(|| eyre!("brew-cask: command_wrapper metadata must be an array"))?;
let name = values
.first()
.and_then(Value::as_str)
.ok_or_else(|| eyre!("brew-cask: command_wrapper requires a command name"))?;
let name_path = Path::new(name);
if name_path.file_name().and_then(|name| name.to_str()) != Some(name)
|| matches!(name, "." | "..")
{
bail!("brew-cask: command_wrapper requires a command name without path components");
}
let options = values
.get(1)
.and_then(Value::as_object)
.ok_or_else(|| eyre!("brew-cask: command_wrapper requires options"))?;
let mut unsupported = options
.keys()
.filter(|key| !matches!(key.as_str(), "content" | "executable" | "args" | "env"))
.cloned()
.collect::<Vec<_>>();
unsupported.sort();
if !unsupported.is_empty() {
bail!(
"brew-cask: command_wrapper has unsupported option {}",
unsupported.join(", ")
);
}
let content = optionsView on GitHub (pinned to afd2eddd3a)
Solutions
- Use only the bare command/file name without '/' or '.' components, e.g. 'mytool' instead of 'bin/mytool'.
- Verify the name is not '.' or '..'.
- If the executable lives in a subdirectory, express that elsewhere (e.g. in the executable/content options) and keep name as the final component.
Example fix
// before
"command_wrapper" => json!(["bin/mytool", {"executable": "mytool"}])
// after
"command_wrapper" => json!(["mytool", {"executable": "mytool"}]) Defensive patterns
Strategy: validation
Validate before calling
fn valid_cw_name(name: &str) -> bool {
let p = std::path::Path::new(name);
p.file_name().and_then(|f| f.to_str()) == Some(name) && !matches!(name, "." | "..")
}
assert!(valid_cw_name("mytool")); Type guard
fn valid_cw_name(name: &str) -> bool {
std::path::Path::new(name)
.file_name()
.and_then(|f| f.to_str())
== Some(name)
&& !matches!(name, "." | "..")
} Prevention
- Always use the bare binary name in command_wrapper name fields
- Add a lint/test validating no '/' in command names
- Never use '.' or '..' as artifact names
When it happens
Trigger: Parsing a cask artifact stanza whose command_wrapper `name` value is a string containing '/' or path separators, is '.' or '..', or whose final path component does not equal the whole string.
Common situations: Copy-pasting an executable path from a Homebrew formula or absolute install path into the command_wrapper name field; authoring a cask definition by hand and using 'bin/foo' instead of 'foo'.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- oci mount_point must be an absolute path (got {mount_point:?
- path "{path_raw}" must be absolute or start with ~/, ignorin
- brew-cask: command_wrapper has unsupported option {}
- brew-cask: command_wrapper requires content or executable
- brew-cask: command_wrapper requires content or executable, n
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/2045b2cb6bd3a54a.
Report an issue: GitHub.