{"record":{"id":"6ded5bca342c6271","repo":"jdx/mise","slug":"brew-cask-invalid-kind-value-6ded5b","errorCode":null,"errorMessage":"brew-cask: invalid {kind} '{value}'","messagePattern":"brew-cask: invalid (.+?) '(.+?)'","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/packages/brew/cask/fetch.rs","lineNumber":144,"sourceCode":"        bail!(\n            \"brew-cask: requested token '{requested_token}' does not match API token '{}'\",\n            cask.token\n        );\n    }\n    Ok(())\n}\n\npub(super) fn validate_cask_path_component(kind: &str, value: &str) -> Result<()> {\n    let mut components = Path::new(value).components();\n    let valid = !value.is_empty()\n        && !value.contains('\\0')\n        && !value.contains('\\\\')\n        && matches!(components.next(), Some(Component::Normal(_)))\n        && components.next().is_none()\n        && value != \".metadata\"\n        && !value.starts_with(\".mise-\");\n    if !valid {\n        bail!(\"brew-cask: invalid {kind} '{value}'\");\n    }\n    Ok(())\n}\n\npub(super) async fn fetch_and_stage(cask: &Cask, pr: Option<&dyn SingleReport>) -> Result<PathBuf> {\n    if cask.url.ends_with(\".git\") {\n        return fetch_git_clone_and_stage(cask, pr).await;\n    }\n    let archive = fetch_archive(cask, pr).await?;\n    extract_archive(cask, &archive, pr)\n}\n\npub(super) async fn fetch_git_clone_and_stage(\n    cask: &Cask,\n    pr: Option<&dyn SingleReport>,\n) -> Result<PathBuf> {\n    let extract_dir = crate::dirs::CACHE\n        .join(\"system-brew\")","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/packages/brew/cask/fetch.rs#L126-L162","documentation":"mise validates cask path components (API token and version) before using them in filesystem/cache paths. The value must be a single, non-empty, normal path component: no empty string, NUL, backslash, leading '.', traversal ('..' / root / prefix), and must not be the reserved name '.metadata' or start with '.mise-'. When the token or version reported by the cask metadata violates any of these rules, the fetch is aborted with this error to prevent path injection and cache collisions.","triggerScenarios":"Calling a brew-cask-backed install (fetch_cask) or validate_cask_identity with cask metadata whose token or version is empty, contains '/', '\\\\', '\\0', starts with '.', equals '.metadata', or starts with '.mise-'; e.g. a tap serving a cask JSON with a version like '../x', '.metadata', or an empty token.","commonSituations":"Third-party or homemade taps with malformed cask JSON; an upstream cask whose version field changed to a non-standard value; a misconfigured alias/old_tokens entry feeding a bad token; a corrupted or hand-edited cask metadata cache.","solutions":["Check the cask metadata source (official API JSON or tap file) and fix the token/version fields to a single normal path component.","Clear the cached cask metadata (mise cache for system-brew) and retry so stale bad metadata is refetched.","If the cask is from a third-party tap that mise cannot validate, install it with the brew CLI directly instead of mise.","Report/patch the offending cask upstream so its version/token becomes a valid component."],"exampleFix":"// offending cask metadata\n{\"token\": \"my app\", \"version\": \".metadata\"}\n// after (valid single component)\n{\"token\": \"my-app\", \"version\": \"1.2.3\"}","handlingStrategy":"validation","validationCode":"fn valid_cask_component(v: &str) -> bool {\n    use std::path::{Component, Path};\n    let mut c = Path::new(v).components();\n    !v.is_empty() && !v.contains('\\0') && !v.contains('\\\\')\n        && matches!(c.next(), Some(Component::Normal(_)))\n        && c.next().is_none()\n        && v != \".metadata\" && !v.starts_with(\".mise-\")\n}","typeGuard":"fn is_normal_single_component(v: &str) -> bool {\n    matches!(Path::new(v).components().collect::<Vec<_>>()[..], [Component::Normal(_)])\n}","tryCatchPattern":null,"preventionTips":["Keep cask tokens and versions as plain single path components; never embed '/' or '..' in metadata.","Fetch cask metadata from the official Homebrew API, which enforces token/version shape.","Clear mise's system-brew cache after editing any cask JSON by hand."],"tags":["brew","validation","path-component","package-install"],"backgroundTag":"invalid-argument-value","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"}