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

  1. Re-run the same cask command so the recovery pass removes the leftover target and its record
  2. Or delete the leftover target file named in the error plus its *.recovery record, then retry
  3. 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

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


AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17). Data as JSON: /api/errors/0e1ee2c46f8fb170. Report an issue: GitHub.