{"record":{"id":"663879c21f88fb6e","repo":"jdx/mise","slug":"brew-cask-invalid-kind-field-path","errorCode":null,"errorMessage":"brew-cask:{}: invalid {kind} {field} path {}","messagePattern":"brew-cask:(.+?): invalid (.+?) (.+?) path (.+?)","errorType":"validation","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"src/system/packages/brew/cask.rs","lineNumber":5872,"sourceCode":"            \"brew-cask:{}: unsupported {kind} {field} metadata format\",\n            cask.token\n        )\n    })?;\n    let base = match object.get(\"base\").and_then(Value::as_str) {\n        Some(\"staged_path\") => FlightPathBase::StagedPath,\n        Some(base) => bail!(\n            \"brew-cask:{}: unsupported {kind} {field} base {}\",\n            cask.token,\n            base\n        ),\n        None => bail!(\"brew-cask:{}: unsupported {kind} {field} base\", cask.token),\n    };\n    let path = object\n        .get(\"path\")\n        .and_then(Value::as_str)\n        .ok_or_else(|| eyre!(\"brew-cask:{}: unsupported {kind} {field} path\", cask.token))?;\n    if validate_flight_relative_path(path).is_err() {\n        bail!(\n            \"brew-cask:{}: invalid {kind} {field} path {}\",\n            cask.token,\n            path\n        )\n    }\n    Ok(FlightPath {\n        base,\n        path: path.to_string(),\n    })\n}\n\nfn collect_pkg_receipt_ids(value: &Value, pkg_ids: &mut Vec<String>) {\n    let Some(object) = value.as_object() else {\n        return;\n    };\n    let Some(metadata) = object.get(\"uninstall\") else {\n        return;\n    };","sourceCodeStart":5854,"sourceCodeEnd":5890,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/system/packages/brew/cask.rs#L5854-L5890","documentation":"After accepting base == \"staged_path\", mise runs the flight-path object's \"path\" string through validate_flight_relative_path (src/system/packages/brew/cask.rs:3905), which rejects absolute paths and any '..' component. This bail fires when the declared relative path would escape the staged cask location, so mise refuses before creating any link. It is a containment check: flight paths must stay inside the staged directory they are anchored to.","triggerScenarios":"A cask artifact flight-path object whose \"path\" starts with '/' (e.g. \"/Applications/Foo.app\") or contains a ParentDir segment (e.g. \"../Foo.app\") reaching this parser during install/upgrade.","commonSituations":"Hand-edited or malformed cask definitions in a tap; corrupted cached cask JSON; a malicious or typosquatted tap attempting to link outside the staged path.","solutions":["Inspect the cask payload (`brew info --json=v2 --cask <token>`) and confirm the flight-path \"path\" field is a plain relative path with no leading '/' and no '..' segments","If the cask is from a third-party tap, report/fix the artifact stanza upstream or remove the tap","Clear mise's cached cask JSON (`mise cache clear`) and re-fetch in case the copy is corrupted","Update mise in case a newer release supports the artifact form this cask uses"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":"use std::path::{Component, Path};\nfn is_valid_flight_path_str(p: &str) -> bool {\n    let path = Path::new(p);\n    !path.is_absolute()\n        && !path.components().any(|c| matches!(c, Component::ParentDir))\n        && !p.contains('\\0')\n}","tryCatchPattern":"match parse_flight_path(&value) {\n    Ok(fp) => fp,\n    Err(e) if e.to_string().contains(\"invalid\") && e.to_string().contains(\"path\") => {\n        warn!(\"rejecting unsafe flight path in cask artifact\");\n        continue;\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Never author cask flight paths with leading '/' or '..' segments","Audit third-party taps before adding them — malformed artifact stanzas are rejected at install time","Re-fetch cask JSON after editing a local cask instead of relying on cached copies"],"tags":["brew-cask","path-validation","path-traversal","metadata"],"backgroundTag":"path-traversal-validation","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}