jdx/mise · error

brew-cask: command_wrapper args and env require executable

Error message

brew-cask: command_wrapper args and env require executable

What it means

Thrown when a command_wrapper specifies `content` but also non-empty `args` or `env`. Args and environment only make sense when invoking an external executable; inline content has nothing to attach them to.

Source

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

                .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
                        .as_str()
                        .map(|value| (key.clone(), value.to_string()))
                        .ok_or_else(|| {
                            eyre!("brew-cask: command_wrapper environment values must be strings")
                        })
                })
                .collect::<Result<BTreeMap<_, _>>>()
        })
        .transpose()?
        .unwrap_or_default();
    if content.is_some() && (!args.is_empty() || !env.is_empty()) {
        bail!("brew-cask: command_wrapper args and env require executable");
    }
    Ok(Some(CommandWrapperArtifact {
        name: name.to_string(),
        target: artifact_target(value, values),
        content,
        executable,
        args,
        env,
    }))
}

pub(super) fn parse_pkg_artifact(value: &Value) -> Result<Option<PkgArtifact>> {
    let Some(pkg) = value.as_object().and_then(|o| o.get("pkg")) else {
        return Ok(None);
    };
    match pkg {
        Value::String(source) => Ok(Some(PkgArtifact {
            source: source.clone(),

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Move args/env into the content script itself and remove them from options.
  2. Or switch from `content` to an `executable` wrapper so args/env apply.

Example fix

// before
["mytool", {"content": "#!/bin/sh\necho hi", "args": ["-v"]}]
// after
["mytool", {"executable": "mytool", "args": ["-v"]}]
Defensive patterns

Strategy: validation

Validate before calling

fn cw_content_standalone(o: &serde_json::Value) -> bool {
    if o.get("content").is_some() {
        let no_args = o.get("args").and_then(|a| a.as_array()).map_or(true, |a| a.is_empty());
        let no_env = o.get("env").and_then(|e| e.as_object()).map_or(true, |m| m.is_empty());
        no_args && no_env
    } else { true }
}
assert!(cw_content_standalone(&opts));

Prevention

When it happens

Trigger: Options object with 'content' set and at least one entry in 'args' or 'env'.

Common situations: Switching from executable-based to content-based wrapper without removing args/env; misunderstanding that args/env only apply to executable wrappers.

Related errors


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