jdx/mise · error
these paths keep changing while being protected; nothing…
Error message
these paths keep changing while being protected; nothing was changed: {} What it means
After taking the protective checkpoint, mise re-verifies (up to VERIFY_ROUNDS rounds) that every path it is about to touch still matches what was captured. If paths keep appearing/changing between rounds, it cannot guarantee a consistent restore point and aborts. Nothing was changed.
Solutions
- Stop the process writing those paths (watcher, dev server, running task), then re-run the rollback.
- Exclude the churning paths from the restore scope, or restore a narrower set of stable files.
- Check for a concurrent mise history/rollback process and wait for it to finish.
Defensive patterns
Strategy: validation
Validate before calling
fuser -v <target-paths> 2>/dev/null || echo "no writers detected"
Prevention
- Stop watchers/dev servers before running history restores.
- Run one history operation at a time; avoid concurrent rollback/undo.
- Restore from a quiet tree (no active builds writing to targets).
When it happens
Trigger: A set of target paths is repeatedly found missing or modified across verification rounds in apply_steps, exceeding VERIFY_ROUNDS — e.g. another process writes those files continuously while the rollback is being prepared.
Common situations: A dev server, watcher, build task, or editor actively writing files under the paths being restored; another concurrent mise run touching the same files.
Related errors
- appeared after was protected; nothing more was changed
- changed after it was protected; nothing more was changed
- another history operation is running
- another history operation is running
- brew-cask: : Homebrew took ownership of this cask while…
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/cd3256b97895bb03.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/history/replay.rs:533
.checkpoint
.tree
.snapshot
.clone()
.ok_or_else(|| eyre::eyre!("the protective checkpoint has no content"))?;
let mut missing = vec![];
for step in steps.iter().filter(|step| step.action.mutates()) {
let Some(current) = repo.restored_object_at(&live, &step.tree_path)? else {
continue;
};
if repo.restored_object_at(&before_tree, &step.tree_path)? != Some(current) {
missing.push(step.path.clone());
}
}
if missing.is_empty() {
break;
}
if round >= VERIFY_ROUNDS {
bail!(
"these paths keep changing while being protected; nothing was changed: {}",
missing
.iter()
.map(display_path)
.collect::<Vec<_>>()
.join(", ")
);
}
warn!(
"history: {} path(s) changed after the protective checkpoint; capturing again",
missing.len()
);
scope.recapture_before(&missing)?;
}
let mut touched = vec![];
// deletions deepest first, then writes shallowest first: a directory is
// emptied before the file that replaces it is written, and a directory
// that replaces a file exists before its files are writtenView on GitHub (pinned to 533346cc37)