{"record":{"id":"8a3f59c1cd8fd5c0","repo":"jdx/mise","slug":"brew-cask-pkg-artifacts-require-pkgutil-ids-in-8a3f59","errorCode":null,"errorMessage":"brew-cask:{}: pkg artifacts require pkgutil ids in uninstall metadata","messagePattern":"brew-cask:(.+?): pkg artifacts require pkgutil ids in uninstall metadata","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/packages/brew/cask/artifacts.rs","lineNumber":81,"sourceCode":"        && artifacts.command_wrappers.is_empty()\n        && artifacts.pkgs.is_empty()\n        && artifacts.installers.is_empty()\n        && artifacts.generic.is_empty()\n        && artifacts.fonts.is_empty()\n        && artifacts.completions.is_empty()\n        && artifacts.generated_completions.is_empty()\n    {\n        bail!(\n            \"brew-cask:{}: no supported install artifact found\",\n            cask.token\n        );\n    }\n    artifacts.pkg_ids.sort();\n    artifacts.pkg_ids.dedup();\n    if artifacts.pkgs.is_empty() {\n        artifacts.pkg_ids.clear();\n    } else if artifacts.pkg_ids.is_empty() {\n        bail!(\n            \"brew-cask:{}: pkg artifacts require pkgutil ids in uninstall metadata\",\n            cask.token\n        );\n    }\n    Ok(artifacts)\n}\n\npub(super) fn validate_platform_support(cask: &Cask, artifacts: &CaskArtifacts) -> Result<()> {\n    #[cfg(target_os = \"linux\")]\n    {\n        let font_only = !artifacts.fonts.is_empty()\n            && artifacts.apps.is_empty()\n            && artifacts.binaries.is_empty()\n            && artifacts.command_wrappers.is_empty()\n            && artifacts.pkgs.is_empty()\n            && artifacts.installers.is_empty()\n            && artifacts.generic.is_empty()\n            && artifacts.completions.is_empty()","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/packages/brew/cask/artifacts.rs#L63-L99","documentation":"When a cask contains `pkg` artifacts, the uninstall section of the cask must list `pkgutil:` IDs so the package can later be uninstalled via pkgutil. cask_artifacts collects these pkg_ids and bails if a cask has pkg artifacts but the uninstall metadata supplied none, because installing such a cask would leave it unremovable.","triggerScenarios":"Installing (install_one_with_ancestors) or computing package_state for a cask with `pkg \"Foo.pkg\"` stanzas whose `uninstall` block lacks `pkgutil:` entries (or has an empty list), producing zero collected pkg_ids.","commonSituations":"Hand-written or malformed casks missing the `uninstall pkgutil:` stanza; casks where the pkgutil ids live in a section this parser doesn't read; custom taps written for plain brew (which tolerates the omission) being consumed by this stricter implementation.","solutions":["Open the cask (brew cat --cask <token>) and check that the uninstall block contains `pkgutil: \"com.vendor.package.id\"` entries.","Fix the cask by adding pkgutil IDs under uninstall (find them after installing with `pkgutil --pkgs` or from the receipt inside the pkg).","If you control the tap, add e.g. `uninstall pkgutil: \"com.example.mytool\"` to the cask and commit.","As a workaround, install the underlying pkg directly (`brew install --cask` upstream or `installer -pkg`) and manage removal yourself."],"exampleFix":"// before: pkg without pkgutil ids in uninstall\npkg \"MyTool.pkg\"\nuninstall delete: \"/Applications/MyTool.app\"\n// after\npkg \"MyTool.pkg\"\nuninstall pkgutil: \"com.example.mytool\",\n         delete: \"/Applications/MyTool.app\"","handlingStrategy":"validation","validationCode":"const pkgArtifacts = info.artifacts.filter(a => \"pkg\" in a);\nconst hasPkgutil = JSON.stringify(info.artifacts).includes(\"pkgutil\");\nif (pkgArtifacts.length > 0 && !hasPkgutil)\n  throw new Error(`${token}: pkg cask missing uninstall pkgutil ids`);","typeGuard":null,"tryCatchPattern":"match cask_artifacts(&cask) {\n    Err(e) if e.to_string().contains(\"require pkgutil ids\") => {\n        eprintln!(\"{}: add `uninstall pkgutil:` to the cask before installing\", cask.token);\n    }\n    other => other?,\n}","preventionTips":["Always author pkg-based casks with `uninstall pkgutil:` IDs (find them via `pkgutil --pkgs` after a manual install).","Lint custom taps for pkg stanzas lacking pkgutil uninstall entries.","When porting brew-tolerant casks, expect this stricter check and add the metadata.","Prefer app/binary artifacts over pkg when a cask format choice is yours."],"tags":["brew-cask","homebrew","pkg","uninstall","validation"],"backgroundTag":"missing-required-config-field","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"}