{"record":{"id":"e2da3369a4a9f6c1","repo":"jdx/mise","slug":"incoming-files-changed-while-preparing-adoption-p","errorCode":null,"errorMessage":"incoming files changed while preparing adoption; plan again","messagePattern":"incoming files changed while preparing adoption; plan again","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/sync/graph.rs","lineNumber":61,"sourceCode":"            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()\n                } else {\n                    repo.commit_tree(tree, vec![local, remote], \"merge origin dotfiles\")?\n                }\n            }\n        };\n        Ok(Some(Candidate {","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/history/sync/graph.rs#L43-L79","documentation":"`candidate` verifies that the remote tip's tree still matches the tree observed when the adoption plan was built. This error means incoming origin files changed between planning and applying — the fetched remote moved, so the adoption plan is stale and must be recomputed.","triggerScenarios":"Calling `candidate` with `(None, Some(remote))` where `repo.output_tree_of(remote)` differs from the `tree` argument — i.e. new commits were fetched into UPSTREAM_REF after the plan was made.","commonSituations":"Another machine pushed to origin and a fetch happened between planning and applying; running two sync operations concurrently; a scheduled fetch landed mid-adoption.","solutions":["Recompute the adoption plan against the freshly fetched remote and apply again.","Serialize sync operations so fetch/apply don't interleave.","Re-fetch and verify the remote tip is stable before applying the plan."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"const remoteTree = await sync.outputTreeOf(remoteTip);\nif (remoteTree !== plannedTree) {\n  await sync.refetch();\n  plan = await sync.replan();\n}","typeGuard":"function remoteUnchanged(remoteTree: string, plannedTree: string): boolean {\n  return remoteTree === plannedTree;\n}","tryCatchPattern":"try {\n  await sync.adopt(plan);\n} catch (e) {\n  if (/changed while preparing adoption/.test(String(e))) {\n    await sync.refetchAndReplan(); // retry against the new remote tip\n  } else throw e;\n}","preventionTips":["Fetch once and apply immediately; don't let long gaps separate them.","Pause other machines' pushes during an adoption, or expect to re-plan.","Avoid concurrent fetches from other processes mid-adoption."],"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"}