jdx/mise · error
setup history changed during adoption; retry pull
Error message
setup history changed during adoption; retry pull
What it means
During a setup-history sync pull, the apply routine verifies that the repository heads still match what was observed when the adoption plan was built. If the local or remote head moved between planning and commit, the operation is aborted to avoid adopting a history that no longer matches reality. The message instructs the user to retry, since a fresh pull will re-read current heads.
Source
Thrown at src/system/history/sync/apply.rs:559
if fresh_adoption || inventory_tree.is_some() {
// Verify the whole written batch again before advancing Git. A
// concurrent edit must not become an apparently applied setup.
for step in &ready {
if live_object(repo, &step.path)? != step.pending.object
|| live_permissions(&step.path)? != step.desired_mode
{
bail!(
"{} changed during setup adoption; retry pull",
display_path(&step.path)
);
}
}
for directory in &directories {
directory.verify_written()?;
}
let heads = super::graph::Heads::read(repo)?;
if heads.local != application_head || heads.remote != status.upstream_commit {
bail!("setup history changed during adoption; retry pull");
}
let remote = heads.remote.as_deref().unwrap();
super::files::audit_history(repo, remote, &Default::default())?;
let tree = inventory_tree
.clone()
.unwrap_or(repo.output_tree_of(remote)?);
let candidate = heads
.candidate(repo, &tree)?
.ok_or_else(|| eyre::eyre!("setup branch disappeared during adoption"))?;
candidate.adopt(repo)?;
}
Ok(())
})();
if let Err(error) = &result {
let mut recovery_errors = vec![];
for step in ready
.iter()
.rev()View on GitHub (pinned to afd2eddd3a)
Solutions
- Re-run the pull command; the retry re-plans against current heads.
- Identify the concurrent writer (another mise session, script, or manual git command) and stop it before pulling.
- If heads moved unintentionally, inspect the history repo refs and reconcile before retrying.
Defensive patterns
Strategy: retry
Validate before calling
let heads = Heads::read(repo)?;
if heads.local != application_head || heads.remote != upstream_commit {
// heads moved; re-plan instead of applying
} Prevention
- Run only one mise history sync at a time
- Avoid committing to the history repo manually during pulls
- Retry the pull immediately; it is designed to converge
When it happens
Trigger: Concurrent commit of setup history (another mise process or a manual git commit into the history repo) between reading heads and verifying them in apply; a background push/pull moved heads.remote.
Common situations: Running mise sync/pull in two terminals at once; a cron or IDE plugin committing history during a pull; a user manually editing the history repo while a pull runs.
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
- incoming files changed while preparing adoption; plan again
- {} changed before application; nothing was written
- {} changed while the changes were being applied; nothing mor
- {} changed during setup adoption; retry pull
- saved files changed while preparing publication; plan again
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/649f2480150ac146.
Report an issue: GitHub.