jdx/mise · error

brew-cask:{}: {kind} terminate_process {field} must be a boo

Error message

brew-cask:{}: {kind} terminate_process {field} must be a boolean

What it means

Thrown by parse_optional_flight_bool, the shared helper for boolean step fields. Fields like terminate_process's sudo/must_succeed (and sibling steps' recursive/overwrite/source_glob/uninstall) must be true/false JSON booleans or absent; any other type bails. Note the message text hardcodes 'terminate_process' even when the helper rejects a field of another step kind.

Source

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

                .iter()
                .map(|guard| parse_flight_guard(cask, kind, guard))
                .collect::<Result<Vec<_>>>()
        })
        .transpose()
        .map(|guards| guards.unwrap_or_default())
}

fn parse_optional_flight_bool(
    cask: &Cask,
    kind: &str,
    object: &serde_json::Map<String, Value>,
    field: &str,
    default: bool,
) -> Result<bool> {
    match object.get(field) {
        None => Ok(default),
        Some(Value::Bool(value)) => Ok(*value),
        Some(_) => bail!(
            "brew-cask:{}: {kind} terminate_process {field} must be a boolean",
            cask.token
        ),
    }
}

fn parse_run_command(cask: &Cask, kind: &str, value: Option<&Value>) -> Result<FlightPath> {
    let object = value.and_then(Value::as_object).ok_or_else(|| {
        eyre!(
            "brew-cask:{}: unsupported {kind} run command metadata format",
            cask.token
        )
    })?;
    reject_unsupported_flight_fields(cask, kind, "run command", object, &["base", "path"])?;
    let path = object.get("path").and_then(Value::as_str).ok_or_else(|| {
        eyre!(
            "brew-cask:{}: unsupported {kind} run command path",
            cask.token

View on GitHub (pinned to 6f52dcdf99)

Solutions

  1. Use real JSON booleans: true / false, unquoted
  2. Remove the field to accept its documented default (shown in the step's allowed-fields list in cask.rs)

Example fix

// before
{"type": "terminate_process", "name": "x", "must_succeed": "true"}
// after
{"type": "terminate_process", "name": "x", "must_succeed": true}
Defensive patterns

Strategy: type-guard

Validate before calling

fn flight_bools_ok(step: &serde_json::Value) -> bool {
    ["sudo", "must_succeed", "recursive", "overwrite", "source_glob", "uninstall"]
        .iter()
        .all(|f| match step.get(*f) {
            None | Some(serde_json::Value::Bool(_)) => true,
            Some(_) => false,
        })
}

Type guard

fn is_json_bool_or_absent(v: Option<&serde_json::Value>) -> bool {
    matches!(v, None | Some(serde_json::Value::Bool(_)))
}

Try / catch

match parse_flight_step(&cask, kind, &step) {
    Ok(step) => { /* proceed */ }
    Err(e) if e.to_string().contains("must be a boolean") => {
        eprintln!("step boolean fields take unquoted true/false, not strings or numbers");
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: {"type": "terminate_process", "name": "x", "must_succeed": "true"} — string "true", 1, or null where a boolean is expected; equally a copy/symlink step with "recursive": "yes".

Common situations: Config round-trips through YAML or templates that stringify booleans; authors writing "true" in quotes out of habit; JSON producers emitting 0/1 flags.

Related errors


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