jdx/mise · warning · eyre::Report

receipt is not marked safe for direct-artifact pruning

Error message

receipt is not marked safe for direct-artifact pruning

What it means

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.

Solutions

  1. Uninstall such casks through a path that understands them — `brew uninstall --cask <token>` or mise's pkg-aware uninstall — instead of direct-artifact pruning.
  2. 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.
  3. For pkg-based casks, remove the pkgs via the installer receipts (pkgutil) rather than expecting artifact pruning to handle them.
Defensive patterns

Strategy: validation

Validate before calling

// Only offer direct-artifact pruning for schema-v3, prune-safe, pkg-free receipts
if !(receipt.schema_version == 3 && receipt.prune_safe && receipt.pkg_ids.is_empty()) {
    // route to a pkg-aware uninstall instead of artifact pruning
}

Type guard

fn is_direct_prunable(r: &CaskReceipt) -> bool {
    r.schema_version == 3 && r.prune_safe && r.pkg_ids.is_empty()
}

Try / catch

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.

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22). Data as JSON: /api/errors/41706689894cd659. Report an issue: GitHub.

Appendix: source

Thrown at src/system/packages/brew/cask.rs:7257

            bail!(
                "artifact target is now claimed by another cask: {}",
                target.path.display()
            );
        }
    }
    Ok(())
}

fn validate_cask_prune_candidate(candidate: &CaskPruneCandidate) -> Result<()> {
    if homebrew_metadata_present(&candidate.token) {
        bail!("Homebrew now owns this cask");
    }
    let receipt = &candidate.receipt;
    if read_receipt(&candidate.version_dir)?.as_ref() != Some(receipt) {
        bail!("ownership receipt has changed");
    }
    if receipt.schema_version != 3 || !receipt.prune_safe || !receipt.pkg_ids.is_empty() {
        bail!("receipt is not marked safe for direct-artifact pruning");
    }
    if !receipt.metadata_only_apps.is_empty() {
        bail!("metadata-only app ownership cannot be proven safely during pruning");
    }
    let records = receipt
        .targets
        .iter()
        .map(|record| (record.path.clone(), record))
        .collect::<BTreeMap<_, _>>();
    let expected = receipt
        .apps
        .iter()
        .chain(&receipt.binaries)
        .chain(&receipt.fonts)
        .chain(&receipt.completions)
        .cloned()
        .collect::<BTreeSet<_>>();
    if expected.is_empty()

View on GitHub (pinned to 6f52dcdf99)