jdx/mise · error

brew-cask: command_wrapper requires content or executable

Error message

brew-cask: command_wrapper requires content or executable

What it means

A command_wrapper must be materialized from either literal 'content' (a script body, with $HOMEBREW_PREFIX expansion) or an 'executable' (which mise wraps in a bash exec script). If the options object sets neither, mise has nothing to write and bails immediately after parsing the two fields.

Source

Thrown at src/system/packages/brew/cask.rs:5153

        .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 = options
        .get("args")
        .map(|args| {
            args.as_array()
                .ok_or_else(|| eyre!("brew-cask: command_wrapper args must be an array"))?
                .iter()
                .map(|arg| {
                    arg.as_str()
                        .map(str::to_string)
                        .ok_or_else(|| eyre!("brew-cask: command_wrapper args must be strings"))
                })
                .collect::<Result<Vec<_>>>()

View on GitHub (pinned to 6f52dcdf99)

Solutions

  1. Add 'executable' pointing at a binary inside the staged payload (most common), e.g. {"executable": "MyApp.app/Contents/MacOS/tool"}.
  2. Or add 'content' with the full script body (use $HOMEBREW_PREFIX for prefix-relative paths).
  3. Lint generated metadata to require one of the two keys per wrapper.

Example fix

# before
command_wrapper: [["tool", {"args": ["--fast"]}]]

# after
command_wrapper: [["tool", {"executable": "MyApp.app/Contents/MacOS/tool", "args": ["--fast"]}]]
Defensive patterns

Strategy: validation

Validate before calling

jq -e '.command_wrapper[]? | .[1] | has("content") or has("executable")' cask.json >/dev/null || echo 'wrapper needs content or executable'

Prevention

When it happens

Trigger: Wrapper metadata like ["tool", {"args": [...]}] or ["tool", {}] — options present but both content and executable absent, hitting the (false, false) arm of the match at src/system/packages/brew/cask.rs:5157.

Common situations: Template-generated metadata where the content field failed to render; authors assuming the wrapper wraps the cask's app binary by default; YAML indentation putting the body under the wrong key.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22). Data as JSON: /api/errors/3fcd72bd3c5fdf3e. Report an issue: GitHub.