jdx/mise · error

brew-cask: invalid command_wrapper environment name

Error message

brew-cask: invalid command_wrapper environment name '{key}'

What it means

The `env` object of a `command_wrapper` artifact contains a key that is not a valid shell environment-variable name (as checked by `is_shell_env_name`, e.g. disallowing characters like `=` or leading digits). mise refuses to emit an invalid environment assignment into generated wrappers.

Solutions

  1. Rename the env key to a valid shell identifier (`[A-Za-z_][A-Za-z0-9_]*`)
  2. Move values that are not simple assignments out of `env`
  3. Fix or report the cask upstream

Example fix

// before
env: { "1BAD-VAR": "x" }
// after
env: { "BAD_VAR": "x" }
Defensive patterns

Strategy: validation

Validate before calling

const isShellEnvName = (k) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(k);
Object.keys(envObj).forEach(k => { if (!isShellEnvName(k)) throw new Error(`invalid env name ${k}`); });

Type guard

const hasValidEnvNames = (o) => Object.keys(o).every(k => /^[A-Za-z_][A-Za-z0-9_]*$/.test(k));

Prevention

When it happens

Trigger: A cask command_wrapper with `env` keys like `"1PATH"`, `"MY VAR"`, `"FOO=BAR"`, or empty keys; hand-written or corrupted cask metadata.

Common situations: Typoed or copy-pasted env entries in custom taps; attempts to smuggle shell syntax through env names.

Understand the failure class

Background: "is not a valid" / "Invalid ... value" environment variable errors: how libraries validate env vars and what to do when they reject yours — this error's family across 48 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/831447220c863705. Report an issue: GitHub.

Appendix: source

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

    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
                        .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),

View on GitHub (pinned to 533346cc37)