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

  1. Re-run the pull command; the retry re-plans against current heads.
  2. Identify the concurrent writer (another mise session, script, or manual git command) and stop it before pulling.
  3. 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

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


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/649f2480150ac146. Report an issue: GitHub.