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
- Read both parts of the message: fix the rollback error first (usually a permissions or missing-backup issue) so you can manually restore files.
- Manually restore affected targets from the backups referenced in the error, or re-create the original files.
- 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
- Run add with a writable HOME/config and sufficient disk space.
- Never modify dotfile targets or the mise config while an add is running.
- Keep backups intact until the command reports success.
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
- {}
- failed rename: {} -> {}: {err}
- tracking declarations updated, but could not commit the chan
- failed to locate Git repository for {}: {}
- failed to list Git-tracked files in {}: {}
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/ab44606ed494e96c.
Report an issue: GitHub.