jdx/mise · error
the refreshed plan has conflicts; nothing was changed
Error message
the refreshed plan has conflicts; nothing was changed
What it means
When `mise history` applies a replay plan, it re-plans against the live tree if the working tree changed since the plan was shown. If the refreshed plan contains any Action::Conflict steps, mise refuses to proceed so no user data is silently clobbered. This is a deliberate safety abort, not a bug.
Source
Thrown at src/system/history/replay.rs:502
) -> Result<Vec<PathBuf>> {
let _ = (store, entries);
let mut round = 0;
let mut live;
loop {
round += 1;
// editors may have written while the prompt was open: re-plan
live = live_tree(repo, tracked)?;
let fresh = plan(repo, exec, &live)?;
let changed = actionable(&fresh) != actionable(steps);
if changed {
*steps = fresh.clone();
miseprintln!("history: the working tree changed since the plan was shown:");
print_plan(steps, exec, tracked)?;
if steps
.iter()
.any(|step| matches!(step.action, Action::Conflict(_)))
{
bail!("the refreshed plan has conflicts; nothing was changed");
}
if !exec.yes && !prompt::confirm("history: apply the refreshed plan?")?.is_yes() {
bail!("declined; nothing was changed");
}
}
// completeness: every path about to be written or deleted that exists
// now must be captured, as it is now, in the protective checkpoint
let Some((before_id, _)) = scope.before() else {
bail!("no protective checkpoint could be taken; nothing was changed");
};
let before = store::entry(store, before_id)?;
let before_tree = before
.checkpoint
.tree
.snapshot
.clone()
.ok_or_else(|| eyre::eyre!("the protective checkpoint has no content"))?;
let mut missing = vec![];View on GitHub (pinned to afd2eddd3a)
Solutions
- Commit or stash the concurrent working-tree changes, then re-run the replay so the refreshed plan is conflict-free
- Inspect the refreshed plan printed above the error and manually resolve the conflicting paths
- Re-run with the tree in a stable state (close editors/watchers) and apply again
Defensive patterns
Strategy: validation
Validate before calling
// before applying, ensure no conflicts exist in the refreshed plan
if steps.iter().any(|s| matches!(s.action, Action::Conflict(_))) {
eprintln!("resolve conflicts before applying");
return;
} Prevention
- Keep the working tree quiet (no watchers/builds) while reviewing history plans
- Apply plans promptly instead of leaving them open for confirmation
- Use --yes only when the tree is known stable
When it happens
Trigger: Running `mise history` replay/apply without --yes after files were modified between plan display and confirmation, such that the re-computed plan detects a conflict (target path differs from both snapshot and what was shown).
Common situations: An editor, build tool, or another mise process writes files while the user is reviewing the plan prompt; applying an old plan to a tree that has since changed.
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
- declined; nothing was changed
- no protective checkpoint could be taken; nothing was changed
- these paths keep changing while being protected; nothing was
- {} changed after it was protected; nothing more was changed
- {} appeared after {} was protected; nothing more was changed
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/914618bd1ec1bd6a.
Report an issue: GitHub.