jdx/mise · error · eyre::Report
receipt target inventory contains an unclassified path
Error message
receipt target inventory contains an unclassified path
What it means
Every path in the receipt's targets inventory must be classifiable as an app, binary, font, or completion. This error means a target record exists whose path is in none of those lists — typically flight/generic artifacts or categories this prune implementation does not know how to remove — so the whole cask is refused rather than leaving untracked files behind.
Source
Thrown at src/system/packages/brew/cask.rs:7035
.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()
|| records.len() != receipt.targets.len()
|| records.len() != expected.len()
{
bail!("receipt target inventory is incomplete or duplicated");
}
if records.keys().any(|path| !expected.contains(path)) {
bail!("receipt target inventory contains an unclassified path");
}
for path in &receipt.apps {
let record = records
.get(path)
.ok_or_else(|| eyre!("missing app target record"))?;
if record.fingerprint.kind != CaskTargetKind::Directory
|| !allowed_appdir_roots()?
.iter()
.any(|root| path_is_below(path, root))
|| !path.file_name().is_some_and(|name| {
staged_app_matches_target(record, &candidate.version_dir.join(name))
})
{
bail!(
"app target is outside an allowed Applications directory: {}",
path.display()
);View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Diff the targets array against the apps/binaries/fonts/completions arrays in .mise-cask.toml and remove the unclassified entry or reinstall the cask
- Uninstall the cask via 'mise brew uninstall' (full uninstall path) instead of pruning, since it handles flight/generic artifacts
- Upgrade mise so its prune validator understands the artifact category in the receipt
Defensive patterns
Strategy: validation
Validate before calling
// Reject receipts containing target paths outside the classified categories.
fn all_targets_classified(r: &CaskReceipt) -> bool {
let expected: BTreeSet<&Path> = r.apps.iter()
.chain(&r.binaries).chain(&r.fonts).chain(&r.completions)
.map(|p| p.as_path()).collect();
r.targets.iter().all(|t| expected.contains(t.path.as_path()))
} Type guard
fn has_unclassified_targets(r: &CaskReceipt) -> bool {
let expected: std::collections::BTreeSet<&Path> = r.apps.iter()
.chain(&r.binaries).chain(&r.fonts).chain(&r.completions)
.map(|p| p.as_path()).collect();
r.targets.iter().any(|t| !expected.contains(t.path.as_path()))
} Try / catch
// Catch at plan level and downgrade to a per-cask skip with the token named.
match validate_cask_prune_candidate(&candidate) {
Ok(()) => candidates.push(candidate),
Err(reason) => plan.skipped.push(CaskPruneSkip { token: candidate.token, reason: format!("{reason:#}") }),
} Prevention
- Use the full uninstall path for casks with flight/generic artifacts; prune only covers apps/binaries/fonts/completions
- Reinstall casks when upgrading or downgrading mise so the receipt taxonomy matches the tool
When it happens
Trigger: validate_cask_prune_candidate: records.keys().any(|path| !expected.contains(path)). A receipt whose targets include flight_targets or generic_artifact_targets entries (these casks normally carry a prune_blocker and never reach validation), or a receipt from a newer schema with an unknown artifact category.
Common situations: Receipt written by a newer/older mise version with a different artifact taxonomy; hand-added entries to targets; mixing receipts across versions after a downgrade.
Related errors
- ownership receipt has changed
- receipt is not marked safe for direct-artifact pruning
- receipt target inventory is incomplete or duplicated
- app target is outside an allowed Applications directory: {}
- binary target is not an owned Caskroom symlink: {}
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/138aef5dec35f4c2.
Report an issue: GitHub.