jdx/mise · error · eyre::Report
receipt target inventory is incomplete or duplicated
Error message
receipt target inventory is incomplete or duplicated
What it means
Before pruning, the receipt's targets list is cross-checked against the union of its classified artifact lists (apps + binaries + fonts + completions). The error fires when that expected set is empty, when the path->record map is smaller than targets (duplicate paths collapsed by the BTreeMap), or when the counts disagree — i.e. the receipt is internally inconsistent and cannot be trusted to describe what is safe to delete.
Source
Thrown at src/system/packages/brew/cask.rs:7032
}
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()
|| 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!(View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Read Caskroom/<token>/<version>/.mise-cask.toml and verify every path in [[targets]] also appears in apps/binaries/fonts/completions exactly once with no duplicates
- Reinstall the cask to let write_receipt_with_flight_targets regenerate a consistent receipt
- If the file is corrupted beyond repair, uninstall and reinstall the cask, or delete the version directory manually after verifying no symlinks point into it
Defensive patterns
Strategy: validation
Validate before calling
// Verify a receipt is internally consistent before handing it to prune.
use std::collections::{BTreeMap, BTreeSet};
fn inventory_consistent(r: &CaskReceipt) -> bool {
let records: BTreeMap<&Path, _> = r.targets.iter().map(|t| (t.path.as_path(), t)).collect();
let expected: BTreeSet<&Path> = r.apps.iter()
.chain(&r.binaries).chain(&r.fonts).chain(&r.completions)
.map(|p| p.as_path()).collect();
!expected.is_empty()
&& records.len() == r.targets.len()
&& records.len() == expected.len()
} Type guard
fn receipt_inventory_ok(r: &CaskReceipt) -> bool {
let dup = r.targets.len() != r.targets.iter().map(|t| &t.path).collect::<std::collections::BTreeSet<_>>().len();
!dup && !r.apps.is_empty() || !r.binaries.is_empty() || !r.fonts.is_empty() || !r.completions.is_empty()
} Try / catch
if let Err(reason) = validate_cask_prune_candidate(&candidate) {
plan.skipped.push(CaskPruneSkip { token, reason: format!("recorded artifacts cannot be removed safely: {reason:#}") });
continue;
} Prevention
- Never hand-edit .mise-cask.toml — regenerate by reinstalling
- Keep one mise version installing into a prefix; mixed-version receipts drift inconsistent
- Treat inventory errors as corruption: reinstall the cask rather than patching the file
When it happens
Trigger: validate_cask_prune_candidate: expected.is_empty() || records.len() != receipt.targets.len() || records.len() != expected.len(). Produced by a .mise-cask.toml with the same path listed twice in targets, targets missing entries that apps/binaries/fonts/completions reference (or vice versa), or an all-empty receipt.
Common situations: Hand-edited or merge-conflicted receipt file; receipt truncated by a crash mid-write; a bug or incompatible version writing inconsistent receipts; disk corruption.
Related errors
- ownership receipt has changed
- receipt is not marked safe for direct-artifact pruning
- receipt target inventory contains an unclassified path
- 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/bcce9541b7eb9bb6.
Report an issue: GitHub.