{"record":{"id":"5a51a9972dca254a","repo":"jdx/mise","slug":"brew-cask-kind-field-must-be-a-boolean","errorCode":null,"errorMessage":"brew-cask:{}: {kind} {field} must be a boolean","messagePattern":"brew-cask:(.+?): (.+?) (.+?) must be a boolean","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/packages/brew/cask/artifacts.rs","lineNumber":885,"sourceCode":"                .iter()\n                .map(|guard| parse_flight_guard(cask, kind, guard))\n                .collect::<Result<Vec<_>>>()\n        })\n        .transpose()\n        .map(|guards| guards.unwrap_or_default())\n}\n\npub(super) fn parse_optional_flight_bool(\n    cask: &Cask,\n    kind: &str,\n    object: &serde_json::Map<String, Value>,\n    field: &str,\n    default: bool,\n) -> Result<bool> {\n    match object.get(field) {\n        None => Ok(default),\n        Some(Value::Bool(value)) => Ok(*value),\n        Some(_) => bail!(\"brew-cask:{}: {kind} {field} must be a boolean\", cask.token),\n    }\n}\n\npub(super) fn parse_run_command(\n    cask: &Cask,\n    kind: &str,\n    value: Option<&Value>,\n) -> Result<FlightPath> {\n    let object = value.and_then(Value::as_object).ok_or_else(|| {\n        eyre!(\n            \"brew-cask:{}: unsupported {kind} run command metadata format\",\n            cask.token\n        )\n    })?;\n    reject_unsupported_flight_fields(cask, kind, \"run command\", object, &[\"base\", \"path\"])?;\n    let path = object.get(\"path\").and_then(Value::as_str).ok_or_else(|| {\n        eyre!(\n            \"brew-cask:{}: unsupported {kind} run command path\",","sourceCodeStart":867,"sourceCodeEnd":903,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/packages/brew/cask/artifacts.rs#L867-L903","documentation":"Boolean flight-step fields parsed via parse_optional_flight_bool (e.g. `must_succeed`, step-specific flags on Copy/Symlink/Run/terminate_process) must be actual booleans or absent. A non-boolean value (string \"true\", number 1, etc.) causes this bail with the offending field name interpolated.","triggerScenarios":"A cask sets e.g. `must_succeed = \"yes\"` or `force = 1` on a Copy, Symlink, Run, or terminate_process step; parse_flight_step or a step-specific parser calls parse_optional_flight_bool and the `Some(_)` arm fires.","commonSituations":"YAML/TOML tooling coercing true to \"true\"; hand-writing 1/0 instead of true/false; generators emitting quoted booleans; copy-paste from formats where truthy strings are allowed.","solutions":["Change the field to a real boolean literal: `must_succeed = true` (unquoted).","Remove the key to accept the field's default value.","Fix the generator/template that is quoting or coercing the boolean."],"exampleFix":"// before\n[[install.flight_steps]]\ntype = \"run\"\ncommand = { base = \"staged_path\", path = \"bin/setup\" }\nmust_succeed = \"true\"\n// after\n[[install.flight_steps]]\ntype = \"run\"\ncommand = { base = \"staged_path\", path = \"bin/setup\" }\nmust_succeed = true","handlingStrategy":"validation","validationCode":"const BOOL_FIELDS = ['must_succeed', 'force', 'should_fail'];\nfunction validateBooleans(step) {\n  for (const f of BOOL_FIELDS) {\n    if (f in step && typeof step[f] !== 'boolean') {\n      throw new Error(`${f} must be a boolean, got ${JSON.stringify(step[f])}`);\n    }\n  }\n}","typeGuard":"const isBoolField = (v) => v === undefined || typeof v === 'boolean';","tryCatchPattern":null,"preventionTips":["Write true/false unquoted in TOML, never \"true\"/\"yes\"/1.","Quote-check generated configs — generators often stringify booleans.","Run `mise` parse (or schema lint) on casks in CI before release."],"tags":["brew-cask","config-validation","type-mismatch","boolean"],"backgroundTag":"config-type-mismatch","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}