jdx/mise · error

interrupted file recovery needs attention; temporary recover

Error message

interrupted file recovery needs attention; temporary recovery data was retained. {}. Run `mise bootstrap dotfiles recover` to retry, or inspect the files and use `recover <operation> --keep-current` to explicitly accept their current contents

What it means

recover_entries iterates the recorded paths of an interrupted operation and attempts recover_path for each. Any per-path failures are collected, and if any exist it bails with a summary listing each failing path, deliberately leaving the temporary recovery data in place so recovery can be retried or explicitly accepted.

Source

Thrown at src/system/history/recovery.rs:56

            continue;
        }
        let after = journal.iter().rev().find_map(|entry| match entry {
            JournalEntry::Committed {
                seq: recorded,
                after,
            } if *recorded as usize == seq => Some(after),
            _ => None,
        });
        if unfinished_only && after.is_some() {
            continue;
        }
        if let Err(error) = recover_path(state_dir, path, prior, after) {
            blocked.push(path);
            failures.push(format!("{}: {error:#}", crate::file::display_path(path)));
        }
    }
    if !failures.is_empty() {
        bail!(
            "interrupted file recovery needs attention; temporary recovery data was retained. {}. Run `mise bootstrap dotfiles recover` to retry, or inspect the files and use `recover <operation> --keep-current` to explicitly accept their current contents",
            failures.join("; ")
        );
    }
    Ok(())
}

fn recover_path(
    state_dir: &Path,
    path: &Path,
    prior: &PathSnapshot,
    after: Option<&PathState>,
) -> Result<()> {
    validate_destination(path)?;
    let comparison = tempfile::tempdir()?;
    let depth = if matches!(prior, PathSnapshot::Directory { .. }) {
        Capture::Shallow
    } else {

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Run `mise bootstrap dotfiles recover` again — transient conditions may now pass and the retry uses retained recovery data.
  2. Inspect each listed path; if its current contents are correct, run `recover <operation> --keep-current` to accept them explicitly.
  3. Fix the specific per-path cause (see the path:error details in the message), then retry recovery.
  4. Restore the affected files from backup and re-run bootstrap enrollment.

Example fix

// before: retry blindly fails again
$ mise bootstrap dotfiles recover
// after: accept current contents for reviewed files
$ mise bootstrap dotfiles recover <operation> --keep-current
Defensive patterns

Strategy: try-catch

Try / catch

match recover_entries(state_dir, plan) {
    Err(e) if e.to_string().contains("interrupted file recovery needs attention") => {
        eprintln!("{e}\nreview each path, then use --keep-current if contents are correct");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling recover or recover_unfinished when recover_path fails for one or more paths — e.g. the live file changed after the operation, completion was never recorded, or directory contents cannot be verified.

Common situations: Recovering after a crash mid-write while the user has since edited the affected dotfiles; missing 'after' state because the operation died before checkpointing; directories whose identity cannot be established.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/87a9bd08388944ad. Report an issue: GitHub.