jdx/mise · error
local files were saved after enrollment planning; retry pull
Error message
local files were saved after enrollment planning; retry pull
What it means
Before adopting the enrollment/restore plan, mise composes the planned restore tree and compares it against the complete local tree. If they differ, local files were modified after enrollment planning computed the plan, so the plan is stale and the pull is aborted with this error, asking you to retry. Nothing is written; retrying recomputes a fresh plan.
Source
Thrown at src/system/history/sync/apply.rs:475
.as_deref()
.ok_or_else(|| eyre::eyre!("local history disappeared"))?;
// The operation's own protective commit may save the unsaved
// versions that an explicit --take-remote decision will replace.
// Permit only changes at those preflighted paths; any other saved
// change requires a fresh complete plan.
let restore_planned = ready
.iter()
.map(|step| {
Ok(crate::system::history::shadow::Overlay {
path: step.pending.branch_path.clone(),
object: repo.object_at(local, &step.pending.branch_path)?,
})
})
.collect::<Result<Vec<_>>>()?;
if repo.compose(&repo.output_tree_of(current)?, &restore_planned)?
!= repo.output_tree_of(local)?
{
bail!("local files were saved after enrollment planning; retry pull");
}
// Do not let a divergent text merge or a stale resolution differ
// from the complete tree that will be adopted.
for step in &ready {
if repo.restored_object_at(tree, &step.pending.branch_path)? != step.pending.object
{
bail!(
"{} changed in the complete repository merge; reconcile again",
display_path(&step.path)
);
}
}
let candidate = heads
.candidate(repo, tree)?
.ok_or_else(|| eyre::eyre!("setup branch disappeared"))?;
super::files::audit_history(repo, &candidate.commit, &Default::default())?;
}
// Validate the complete batch again after acquiring the operationView on GitHub (pinned to afd2eddd3a)
Solutions
- Re-run `mise bootstrap dotfiles pull` to rebuild the plan against the current tree — this is the explicitly suggested action in the message.
- Ensure no other process (editors, other mise instances, sync daemons) modifies tracked files during pull; run pull exclusively.
- If changes were unintentional, restore the files to the planned state or re-enroll so the plan and tree converge.
Example fix
// before: stale plan detected
bail!("local files were saved after enrollment planning; retry pull");
// after: caller-side handling
match pull().await {
Err(e) if e.to_string().contains("retry pull") => pull().await, // rebuild plan
other => other,
} Defensive patterns
Strategy: retry
Validate before calling
# ensure no other process is editing tracked dotfiles during pull fuser -v ~/.zshrc 2>/dev/null || true # example: check for concurrent writers
Try / catch
async function pullWithReplan() {
try { return await pull(); }
catch (e) {
if (/retry pull/.test(e.message)) return await pull(); // rebuild the plan once
throw e;
}
} Prevention
- Run pull exclusively — close editors and stop dotfile daemons/watchers during it.
- Apply pulls soon after planning; don't leave long gaps on machines with active config churn.
- Re-run pull after any intentional local change instead of applying an old plan.
When it happens
Trigger: During pull, `repo.compose(output_tree_of(current), restore_planned) != output_tree_of(local)` — any live file under tracking changed between when the enrollment plan was built and when apply ran.
Common situations: An editor, dotfile manager, or package installer touched dotfiles between planning and apply; a concurrently running second `mise bootstrap dotfiles` command; long gaps between planning and applying on a machine with active config churn.
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
- {} changed in the complete repository merge; reconcile again
- {} changed before application; nothing was written
- {} changed while the changes were being applied; nothing mor
- {} changed during setup adoption; retry pull
- cannot synchronize: {reason}
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/bb346950a4d2a806.
Report an issue: GitHub.