{"record":{"id":"43de3edcae63493e","repo":"jdx/mise","slug":"brew-cask-requested-token-requested-token-doe","errorCode":null,"errorMessage":"brew-cask: requested token '{requested_token}' does not match API token '{}'","messagePattern":"brew-cask: requested token '(.+?)' does not match API token '(.+?)'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/packages/brew/cask.rs","lineNumber":951,"sourceCode":"                 Tapped casks must publish API metadata at api/cask/<token>.json\"\n            )\n        })?;\n    cask.raw_base = raw_base;\n    validate_cask_identity(&cask, requested_token, official_api)?;\n    Ok(cask)\n}\n\nfn validate_cask_identity(cask: &Cask, requested_token: &str, official_api: bool) -> Result<()> {\n    validate_cask_path_component(\"API token\", &cask.token)?;\n    validate_cask_path_component(\"version\", &cask.version)?;\n    let trusted_alias = official_api\n        && cask\n            .aliases\n            .iter()\n            .chain(&cask.old_tokens)\n            .any(|alias| alias == requested_token);\n    if cask.token != requested_token && !trusted_alias {\n        bail!(\n            \"brew-cask: requested token '{requested_token}' does not match API token '{}'\",\n            cask.token\n        );\n    }\n    Ok(())\n}\n\nfn 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        && 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    }","sourceCodeStart":933,"sourceCodeEnd":969,"githubUrl":"https://github.com/jdx/mise/blob/6f52dcdf99e282ef7a7db68c81301fa4618d0f79/src/system/packages/brew/cask.rs#L933-L969","documentation":"validate_cask_identity (src/system/packages/brew/cask.rs:951) compares the token the user requested with the `token` field of the fetched cask JSON. They must match, unless the request hit the official homebrew/cask API and the requested name appears in the cask's aliases or old_tokens. For third-party taps no alias is trusted, so any mismatch aborts before anything is staged or downloaded further.","triggerScenarios":"Requesting a token that differs from the declared token in the tap's api/cask/<token>.json: renamed casks (old token requested, new token in metadata), case differences (Firefox vs firefox), a tapped cask file whose declared token differs from its filename, or a homebrew-core alias used against a third-party tap.","commonSituations":"Upstream cask renames between versions while user configs still carry the old name; display names typed instead of tokens ('Google Chrome' vs google-chrome); taps that vendored official cask JSON under a local token.","solutions":["Install using the canonical token reported in the error message — it is the cask's declared API token","For renamed official casks, update configs to the new token; aliases/old_tokens keep old names working only on the official API","If you maintain the tap, make the cask file's declared token match the token users request (or add the requested name as an alias if the tap also serves the official API path — aliases are still untrusted there, so renaming is the real fix)"],"exampleFix":"# before (mise.toml)\nname = \"firefox-esr-old\"\n\n# after — use the API token shown in the error\nname = \"firefox-esr\"","handlingStrategy":"validation","validationCode":"let cask: Cask = fetch_cask_json(name).await?;\nif cask.token != requested\n    && !(official_api && cask.aliases.iter().chain(&cask.old_tokens).any(|a| a == requested))\n{\n    return Err(anyhow!(\"use canonical token {} instead of {}\", cask.token, requested));\n}","typeGuard":"fn tokens_match(cask: &Cask, requested: &str, official: bool) -> bool {\n    cask.token == requested\n        || (official && cask.aliases.iter().chain(&cask.old_tokens).any(|a| a == requested))\n}","tryCatchPattern":null,"preventionTips":["Always reference casks by their canonical token from the tap's api/cask JSON","After upstream renames, update configs to the new token — aliases are trusted only on the official API","Token matching is case-sensitive; copy tokens, don't retype display names"],"tags":["brew-cask","token-mismatch","validation","homebrew"],"backgroundTag":"package-identifier-mismatch","analyzedSha":"6f52dcdf99e282ef7a7db68c81301fa4618d0f79","analyzedAt":"2026-08-22T10:14:23.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}