jdx/mise · critical

{err} dotfiles: rollback failed: {rollback_err}

Error message

{err}
dotfiles: rollback failed: {rollback_err}

What it means

When the dotfiles add apply step fails, run_inner attempts to roll back all partial changes (restored targets, backups, config file). If any rollback step also fails, the original error and the rollback error are chained into a single bail: `<err>\ndotfiles: rollback failed: <rollback_err>`. This tells the user that the operation failed AND the automatic restore could not fully undo it, so manual repair may be needed.

Source

Thrown at src/cli/dotfiles/add.rs:488

            if !updated_targets.is_empty() {
                info!("dotfiles: updated {}", updated_targets.join(", "));
            }
            if let Some(plan) = apply_plan {
                apply_started = true;
                system::files::execute_apply(plan, &apply_opts)?;
            }
            Ok(())
        })();
        if let Err(err) = result {
            if let Err(rollback_err) = rollback_add(
                &source_backups,
                &target_backups,
                &mut moved_targets,
                apply_started,
                &config_path,
                original_config.as_deref(),
            ) {
                bail!("{err}\ndotfiles: rollback failed: {rollback_err}");
            }
            return Err(err);
        }
        Ok(())
    }
}

#[derive(Debug)]
struct PlannedAdd {
    target_raw: String,
    target: PathBuf,
    source: PathBuf,
    mode: FileMode,
    implied_source: bool,
    explicit_mode: bool,
    already_managed: Option<FileRequest>,
}

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Read both parts of the message: fix the rollback error first (usually a permissions or missing-backup issue) so you can manually restore files.
  2. Manually restore affected targets from the backups referenced in the error, or re-create the original files.
  3. Fix the root-cause condition (permissions/disk/same-filesystem source) and re-run `mise bootstrap dotfiles add`.

Example fix

# fix permissions preventing rollback, then retry
sudo chown -R "$USER" ~/.config/backups  # or the path named in the rollback error
mise bootstrap dotfiles add ~/.zshrc --source ~/dotfiles/zshrc
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight: writable paths, same device, enough space
import { accessSync, constants, statfsSync } from 'node:fs';
accessSync(sourceDir, constants.W_OK);
accessSync(targetDir, constants.W_OK);
if (statfsSync(sourceDir).dev !== statfsSync(targetDir).dev) throw new Error('cross-device source');

Try / catch

try {
  execSync(`mise bootstrap dotfiles add ${target} --source ${source}`);
} catch (e) {
  if (String(e.stderr).includes('rollback failed')) {
    console.error('Partial apply AND failed rollback: manually restore from backups before retrying.');
  } else throw e;
}

Prevention

When it happens

Trigger: Any failure during apply (e.g. copy/symlink errors) combined with a failing rollback action — backup files missing, restore_path errors like permission denied, config restore failing, or leftover moved targets that couldn't be moved back.

Common situations: Permissions problems on dotfile paths or backups directory; backups removed/cleaned mid-run; cross-device moves failing during restore; running out of disk space during recovery.

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/ab44606ed494e96c. Report an issue: GitHub.