jdx/mise · error
brew-cask: unresolved recovery for newly created target
Error message
brew-cask: unresolved recovery for newly created target {} What it means
Same pre-flight scan (ensure_no_unresolved_flight_recovery), but the matching FlightRecoveryRecord has no backup — it was written when the transaction created a brand-new target that must be removed if the operation doesn't commit. An outstanding record means a previous run created this path and died before finishing, so mise refuses to operate on it again until that state is resolved.
Solutions
- Re-run the same mise brew command so built-in recovery finishes removing the created target
- Or remove the newly created target manually plus its *.recovery record, then retry
- Open the record JSON and use its target field to identify exactly which path is pending
- Let mise roll back rather than killing it mid-cask-operation
Example fix
# before: stale absent-record $ mise brew install --cask foo # refuses: newly created target pending # after $ rm "<target-path-from-error>" $ rm "<state>/brew-cask/flight-recovery/absent-<hash>.recovery" $ mise brew install --cask foo
Defensive patterns
Strategy: validation
Validate before calling
// Detect pending 'absent' recovery records for a target before install.
fn pending_absent_recovery(target: &Path) -> Option<PathBuf> {
let dir = state_dir().join("brew-cask/flight-recovery");
std::fs::read_dir(dir).ok()?.flatten().map(|e| e.path())
.filter(|p| p.extension().is_some_and(|e| e == "recovery"))
.find(|p| std::fs::read_to_string(p).ok()
.and_then(|b| serde_json::from_str::<FlightRecoveryRecord>(&b).ok())
.is_some_and(|r| r.target == target && r.backup.is_none()))
} Try / catch
if let Err(e) = install_cask(&cask) {
if e.to_string().contains("unresolved recovery for newly created target") {
// remove the created target + its absent-*.recovery record, then retry
}
} Prevention
- Re-run the interrupted command first — recovery runs automatically
- Read the record's target field to find the exact pending path
- Remove both the pending target and the record together, never just one
When it happens
Trigger: An interrupted operation that had just created the target file/directory (no prior original existed, hence no backup); the corresponding absent-*.recovery record for it still exists in the flight-recovery directory.
Common situations: Crashed or killed installs leaving newly created files behind; partially written targets blocking every retry of the same cask.
Related errors
- brew-cask: unresolved recovery for
- brew-cask: refusing to restore flight target through a…
- brew-cask: refusing to restore flight target through a…
- brew-cask: unresolved recovery for newly created target
- brew-cask: unresolved recovery for
AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22).
Data as JSON: /api/errors/0e1ee2c46f8fb170.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/packages/brew/cask.rs:3306
.is_none_or(|extension| extension != "recovery")
{
continue;
}
let Ok(body) = file::read_to_string(&path) else {
continue;
};
let Ok(record) = serde_json::from_str::<FlightRecoveryRecord>(&body) else {
continue;
};
if record.target == target {
if let Some(backup) = record.backup {
bail!(
"brew-cask: unresolved recovery for {} still preserves its original at {}",
target.display(),
backup.display()
);
}
bail!(
"brew-cask: unresolved recovery for newly created target {}",
target.display()
);
}
}
Ok(())
}
fn recover_flight_backups() -> Result<()> {
let root = flight_recovery_root();
recover_flight_backups_in(&root)
}
fn recover_flight_backups_in(root: &Path) -> Result<()> {
let Ok(entries) = std::fs::read_dir(root) else {
return Ok(());
};
for entry in entries {View on GitHub (pinned to 6f52dcdf99)