{"record":{"id":"f2333f07134cb310","repo":"jdx/mise","slug":"saved-files-changed-while-preparing-publication-p","errorCode":null,"errorMessage":"saved files changed while preparing publication; plan again","messagePattern":"saved files changed while preparing publication; plan again","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/sync/graph.rs","lineNumber":55,"sourceCode":"                (bases.len() == 1).then(|| bases[0].clone())\n            }\n            _ => None,\n        };\n        Ok(Self {\n            local,\n            remote,\n            base,\n        })\n    }\n\n    /// Preparing a candidate does not advance a branch or write live files.\n    /// The caller must finish its complete application before adopting it.\n    pub(crate) fn candidate(&self, repo: &HistoryRepo, tree: &str) -> Result<Option<Candidate>> {\n        let commit = match (&self.local, &self.remote) {\n            (None, None) => return Ok(None),\n            (Some(local), None) => {\n                if repo.output_tree_of(local)? != tree {\n                    bail!(\"saved files changed while preparing publication; plan again\");\n                }\n                local.clone()\n            }\n            (None, Some(remote)) => {\n                if repo.output_tree_of(remote)? != tree {\n                    bail!(\"incoming files changed while preparing adoption; plan again\");\n                }\n                remote.clone()\n            }\n            (Some(local), Some(remote)) => {\n                if self.base.as_ref() == Some(remote) {\n                    if repo.output_tree_of(local)? != tree {\n                        bail!(\"saved files changed while preparing publication; plan again\");\n                    }\n                    local.clone()\n                } else if self.base.as_ref() == Some(local) && repo.output_tree_of(remote)? == tree\n                {\n                    remote.clone()","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/history/sync/graph.rs#L37-L73","documentation":"`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.","triggerScenarios":"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.","commonSituations":"Another mise process or concurrent command committed local changes while a publication was being prepared; the user edited and re-saved dotfiles mid-operation.","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."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"const plan = sync.plan(tree);\nconst tip = await sync.localTip();\nif (tip && (await sync.outputTreeOf(tip)) !== tree) {\n  plan = await sync.replan(); // recompute before applying\n}","typeGuard":"function planIsCurrent(tipTree: string | null, plannedTree: string): boolean {\n  return tipTree === plannedTree;\n}","tryCatchPattern":"try {\n  await sync.publish(plan);\n} catch (e) {\n  if (/changed while preparing publication/.test(String(e))) {\n    await sync.publish(await sync.replan()); // retry once with a fresh plan\n  } else throw e;\n}","preventionTips":["Run only one sync process at a time.","Plan and apply without interleaving local edits.","Re-plan immediately before applying after any local change."],"tags":["concurrency","stale-state","git"],"backgroundTag":"stale-plan-state","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}