jdx/mise · error

brew-cask: command_wrapper requires content or executable

Error message

brew-cask: command_wrapper requires content or executable

What it means

Cask artifact validation in parse_command_wrapper_artifact: a command_wrapper entry defined neither `content` nor `executable`, so there is nothing to wrap. This mirrors Homebrew cask stanza requirements and fires on an incomplete command_wrapper definition.

Source

Thrown at src/system/packages/brew/cask/artifacts.rs:219

        .collect::<Vec<_>>();
    unsupported.sort();
    if !unsupported.is_empty() {
        bail!(
            "brew-cask: command_wrapper has unsupported option {}",
            unsupported.join(", ")
        );
    }
    let content = options
        .get("content")
        .and_then(Value::as_str)
        .map(str::to_string);
    let executable = options
        .get("executable")
        .and_then(Value::as_str)
        .map(str::to_string);
    match (content.is_some(), executable.is_some()) {
        (false, false) => {
            bail!("brew-cask: command_wrapper requires content or executable")
        }
        (true, true) => {
            bail!("brew-cask: command_wrapper requires content or executable, not both")
        }
        _ => {}
    }
    let args = string_args(options, "command_wrapper")?;
    let env = options
        .get("env")
        .map(|env| {
            env.as_object()
                .ok_or_else(|| eyre!("brew-cask: command_wrapper env must be an object"))?
                .iter()
                .map(|(key, value)| {
                    if !is_shell_env_name(key) {
                        bail!("brew-cask: invalid command_wrapper environment name '{key}'");
                    }
                    value

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Add an `executable` option naming the binary to run.
  2. Alternatively add a `content` option with inline script content.
  3. Remove args/env if you intended content-only, since args/env require executable anyway.

Example fix

// before
["mytool", {}]
// after
["mytool", {"executable": "mytool"}]
Defensive patterns

Strategy: validation

Validate before calling

fn cw_has_body(opts: &serde_json::Map<String, serde_json::Value>) -> bool {
    opts.contains_key("content") || opts.contains_key("executable")
}
assert!(cw_has_body(&opts));

Type guard

fn has_content_or_executable(o: &serde_json::Value) -> bool {
    o.get("content").is_some() || o.get("executable").is_some()
}

Prevention

When it happens

Trigger: A command_wrapper options object that is empty or only contains args/env, so both content and executable resolve to None.

Common situations: Authoring a cask with just a name and args, forgetting to specify what the wrapper runs; deleting the executable line when refactoring a cask definition.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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