{"record":{"id":"41706689894cd659","repo":"jdx/mise","slug":"receipt-is-not-marked-safe-for-direct-artifact-pru","errorCode":null,"errorMessage":"receipt is not marked safe for direct-artifact pruning","messagePattern":"receipt is not marked safe for direct-artifact pruning","errorType":"validation","errorClass":"eyre::Report","httpStatus":null,"severity":"warning","filePath":"src/system/packages/brew/cask.rs","lineNumber":7257,"sourceCode":"            bail!(\n                \"artifact target is now claimed by another cask: {}\",\n                target.path.display()\n            );\n        }\n    }\n    Ok(())\n}\n\nfn validate_cask_prune_candidate(candidate: &CaskPruneCandidate) -> Result<()> {\n    if homebrew_metadata_present(&candidate.token) {\n        bail!(\"Homebrew now owns this cask\");\n    }\n    let receipt = &candidate.receipt;\n    if read_receipt(&candidate.version_dir)?.as_ref() != Some(receipt) {\n        bail!(\"ownership receipt has changed\");\n    }\n    if receipt.schema_version != 3 || !receipt.prune_safe || !receipt.pkg_ids.is_empty() {\n        bail!(\"receipt is not marked safe for direct-artifact pruning\");\n    }\n    if !receipt.metadata_only_apps.is_empty() {\n        bail!(\"metadata-only app ownership cannot be proven safely during pruning\");\n    }\n    let records = receipt\n        .targets\n        .iter()\n        .map(|record| (record.path.clone(), record))\n        .collect::<BTreeMap<_, _>>();\n    let expected = receipt\n        .apps\n        .iter()\n        .chain(&receipt.binaries)\n        .chain(&receipt.fonts)\n        .chain(&receipt.completions)\n        .cloned()\n        .collect::<BTreeSet<_>>();\n    if expected.is_empty()","sourceCodeStart":7239,"sourceCodeEnd":7275,"githubUrl":"https://github.com/jdx/mise/blob/6f52dcdf99e282ef7a7db68c81301fa4618d0f79/src/system/packages/brew/cask.rs#L7239-L7275","documentation":"A cask receipt is only prunable via the direct-artifact path when it was written by receipt schema v3, its prune_safe flag is set, and it has no pkg_ids (nothing was installed through macOS .pkg installers). This error means one of those invariants fails, so mise refuses artifact-level deletion — pkg-installed software needs pkgutil-based uninstall, and older/newer receipt schemas may carry semantics this pruner cannot verify.","triggerScenarios":"Pruning a cask whose receipt has schema_version != 3 (written by a different mise version), prune_safe == false (ownership could not be fully proven at install time), or non-empty pkg_ids (the cask ran .pkg installers that left system receipts behind).","commonSituations":"Upgrading/downgrading mise across versions that changed the receipt schema; pruning casks that bundle .pkg installers (many GUI apps, drivers, VPN clients); casks installed with unusual artifacts.","solutions":["Uninstall such casks through a path that understands them — `brew uninstall --cask <token>` or mise's pkg-aware uninstall — instead of direct-artifact pruning.","If the receipt is simply old-schema, reinstall the cask with the current mise so a fresh v3 receipt with prune_safe is written, then prune.","For pkg-based casks, remove the pkgs via the installer receipts (pkgutil) rather than expecting artifact pruning to handle them."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Only offer direct-artifact pruning for schema-v3, prune-safe, pkg-free receipts\nif !(receipt.schema_version == 3 && receipt.prune_safe && receipt.pkg_ids.is_empty()) {\n    // route to a pkg-aware uninstall instead of artifact pruning\n}","typeGuard":"fn is_direct_prunable(r: &CaskReceipt) -> bool {\n    r.schema_version == 3 && r.prune_safe && r.pkg_ids.is_empty()\n}","tryCatchPattern":"On Err from validate_cask_prune_candidate, record a CaskPruneSkip with the reason and fall back to a full uninstall path rather than aborting the whole prune plan.","preventionTips":["Reinstall legacy-schema casks with the current mise before pruning them.","Keep pkg-installing casks on the pkg-aware uninstall path.","Don't downmise across receipt schema changes and then prune."],"tags":["homebrew","cask","prune","schema","receipt"],"backgroundTag":"schema-validation-failed","analyzedSha":"6f52dcdf99e282ef7a7db68c81301fa4618d0f79","analyzedAt":"2026-08-22T10:14:23.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}