jdx/mise · error
brew-cask: unresolved recovery for newly created target {}
Error message
brew-cask: unresolved recovery for newly created target {} What it means
The no-backup variant of the pending-recovery check: a previous flight created this target from scratch (no original to preserve, so the record has no backup) and never committed. A leftover record means the target may be a half-written file, so new operations on that target are refused until the pending flight is resolved.
Source
Thrown at src/system/packages/brew/cask.rs:3180
.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 9dcfcaa0dc)
Solutions
- Re-run the same cask command so the recovery pass removes the leftover target and its record
- Or delete the leftover target file named in the error plus its *.recovery record, then retry
- If the target must be kept, verify the file is intact and clear only the record
Example fix
# manual cleanup
rm '/path/in/error/target'
rm "${XDG_STATE_HOME:-~/.local/state}/mise/brew-cask/flight-recovery/example.recovery" Defensive patterns
Strategy: retry
Validate before calling
// Detect a pending no-backup flight for this target before operating on it
let root = flight_recovery_root();
if let Ok(entries) = std::fs::read_dir(&root) {
for entry in entries.flatten() {
let path = entry.path();
if path.extension().is_some_and(|e| e == "recovery") {
if let Ok(body) = std::fs::read_to_string(&path) {
if let Ok(record) = serde_json::from_str::<FlightRecoveryRecord>(&body) {
if record.target == target && record.backup.is_none() {
recover_flight_backups()?; // remove leftover target + record
}
}
}
}
}
} Try / catch
match install_cask(&cask) {
Err(e) if e.to_string().contains("unresolved recovery for newly created target") => {
recover_flight_backups()?;
install_cask(&cask)?
}
other => other?,
} Prevention
- Re-run the interrupted cask command so recovery removes half-written targets
- Only delete leftover targets manually after confirming they are garbage
- Avoid force-killing installs during artifact writes
When it happens
Trigger: An interrupted install that had just created a new artifact file and died before the recovery record was cleaned up; a recovery pass unable to delete the leftover target.
Common situations: Same as the backup variant: crashed or cancelled cask installs leaving both the new file and its recovery record behind.
Related errors
- brew-cask: unresolved recovery for {} still preserves its or
- 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/0e1ee2c46f8fb170.
Report an issue: GitHub.