jdx/mise · error
saved files changed while preparing publication; plan again
Error message
saved files changed while preparing publication; plan again
What it means
`candidate` verifies that the tree of the local tip commit still matches the tree the plan was computed from. This error means the local saved files changed between planning and applying the publication — the plan is stale and must be recomputed to avoid publishing the wrong tree.
Solutions
- Re-run the plan (recompute the sync plan) and apply it again.
- Ensure no other mise sync process is running concurrently.
- Re-apply after the concurrent local change has been committed and included in a fresh plan.
Defensive patterns
Strategy: retry
Validate before calling
const plan = sync.plan(tree);
const tip = await sync.localTip();
if (tip && (await sync.outputTreeOf(tip)) !== tree) {
plan = await sync.replan(); // recompute before applying
} Type guard
function planIsCurrent(tipTree: string | null, plannedTree: string): boolean {
return tipTree === plannedTree;
} Try / catch
try {
await sync.publish(plan);
} catch (e) {
if (/changed while preparing publication/.test(String(e))) {
await sync.publish(await sync.replan()); // retry once with a fresh plan
} else throw e;
} Prevention
- Run only one sync process at a time.
- Plan and apply without interleaving local edits.
- Re-plan immediately before applying after any local change.
When it happens
Trigger: Calling `candidate` with `(Some(local), None)` where `repo.output_tree_of(local)` differs from the `tree` argument — i.e. a new local commit was created after the plan was built.
Common situations: Another mise process or concurrent command committed local changes while a publication was being prepared; the user edited and re-saved dotfiles mid-operation.
Related errors
- incoming files changed while preparing adoption; plan again
- origin changed while planning; reconcile again
- could not reuse the fetched setup preview
- history changed during the operation; cannot replace its…
- local saved history changed while planning; reconcile again
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/f2333f07134cb310.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/history/sync/graph.rs:55
(bases.len() == 1).then(|| bases[0].clone())
}
_ => None,
};
Ok(Self {
local,
remote,
base,
})
}
/// Preparing a candidate does not advance a branch or write live files.
/// The caller must finish its complete application before adopting it.
pub(crate) fn candidate(&self, repo: &HistoryRepo, tree: &str) -> Result<Option<Candidate>> {
let commit = match (&self.local, &self.remote) {
(None, None) => return Ok(None),
(Some(local), None) => {
if repo.output_tree_of(local)? != tree {
bail!("saved files changed while preparing publication; plan again");
}
local.clone()
}
(None, Some(remote)) => {
if repo.output_tree_of(remote)? != tree {
bail!("incoming files changed while preparing adoption; plan again");
}
remote.clone()
}
(Some(local), Some(remote)) => {
if self.base.as_ref() == Some(remote) {
if repo.output_tree_of(local)? != tree {
bail!("saved files changed while preparing publication; plan again");
}
local.clone()
} else if self.base.as_ref() == Some(local) && repo.output_tree_of(remote)? == tree
{
remote.clone()View on GitHub (pinned to 533346cc37)