jdx/mise · error
brew-cask: unresolved recovery for {} still preserves its or
Error message
brew-cask: unresolved recovery for {} still preserves its original at {} What it means
When mise moves an existing file aside during artifact installation it writes a flight-recovery record (*.recovery JSON under the state dir) that is removed when the transaction commits. ensure_no_unresolved_flight_recovery scans these records before operating on a target; finding one that still points at a preserved backup means an earlier run was interrupted mid-transaction, so mise refuses rather than risk losing the original.
Source
Thrown at src/system/packages/brew/cask.rs:3174
return Ok(());
};
for entry in entries.flatten() {
let path = entry.path();
if path
.extension()
.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)
}View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Re-run the same cask command: recovery of pending flights runs first and normally completes it
- If the target state is known-good, restore manually: move the backup file (path in the message) back over the target, then delete the matching *.recovery record under the flight-recovery root in mise's state dir
- If recovery cannot complete, report it with the record contents
Example fix
# manual cleanup after confirming the target is fine
mv '/path/in/error/backup' '/path/in/error/target'
rm "${XDG_STATE_HOME:-~/.local/state}/mise/brew-cask/flight-recovery/example.recovery" Defensive patterns
Strategy: retry
Validate before calling
// Before installing over a target, run pending-flight recovery first
let root = flight_recovery_root();
for entry in std::fs::read_dir(&root).ok().into_iter().flatten().flatten() {
let path = entry.path();
if path.extension().is_some_and(|e| e == "recovery") {
recover_flight_backups()?; // complete pending flights before proceeding
break;
}
} Try / catch
match install_cask(&cask) {
Err(e) if e.to_string().contains("unresolved recovery") => {
// a previous run was interrupted: complete recovery, then retry once
recover_flight_backups()?;
install_cask(&cask)?
}
other => other?,
} Prevention
- Let cask installs/upgrades finish instead of killing them mid-flight
- After a crash, re-run the same command so recovery completes before new work
- Do not delete the flight-recovery state dir manually while records exist
When it happens
Trigger: A previous cask install/upgrade was killed (Ctrl-C, crash, reboot) between moving the original aside and committing; the recovery pass after that crash itself failed or never ran.
Common situations: Interrupted upgrades; power loss mid-install; users killing the process when it appeared stuck.
Related errors
- brew-cask: unresolved recovery for newly created target {}
- brew-cask: refusing to restore flight target through a chang
- install from exe
- mise outdated --monorepo is not implemented yet
- mise prune --monorepo is not implemented yet
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/1d0f7cf6cd7d9a05.
Report an issue: GitHub.