jdx/mise · error
local saved history changed while planning; reconcile again
Error message
local saved history changed while planning; reconcile again
What it means
Thrown in build (publish path) when the locally saved history HEAD read now differs from the expected_local hash captured earlier during planning. It is an optimistic-concurrency guard: something modified the local history ref between planning and publication, so the prepared batch is stale and must be recomputed to avoid clobbering changes.
Solutions
- Re-run the sync/pull so planning and publication happen on the current state
- Ensure no other mise process is running history sync concurrently
- If the local history ref was moved manually, restore it or accept the new state and re-plan
- Retry the publish after reconciliation
Example fix
# before: publish prepared earlier against old local head mise dot sync publish # fails if head moved # after: reconcile and retry with fresh expectations mise dot sync reconcile && mise dot sync publish
Defensive patterns
Strategy: retry
Validate before calling
let heads = Heads::read(repo)?;
if heads.local.as_deref() != expected_local {
eprintln!("history moved; re-plan before publishing");
} Try / catch
match build(...) {
Err(e) if e.to_string().contains("changed while planning") => {
// re-read heads, recompute plan, retry once
}
other => other?,
} Prevention
- Avoid running concurrent mise history-sync operations
- Reconcile and re-plan immediately before publishing instead of using stale plans
- Do not manually move/reset history refs while a sync is in progress
When it happens
Trigger: Running a publish whose Heads::read(repo).local no longer equals the expected_local passed from the planning phase — i.e. another mise process or manual git ref update moved the local history branch in between.
Common situations: Two concurrent `mise` history-sync operations (e.g. two shells); a background reconcile process updating history between plan and publish; manually resetting the history branch with git while a publish was prepared.
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
- origin changed while applying this setup; reconcile again…
- cannot onboard this setup repository: history is unavailable
- configuration disappeared from preview commit
- could not snapshot the local history repository for preview
- forced publication is not supported
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/654510ff8117ac5d.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/history/sync/publish.rs:21
use eyre::{Result, bail};
use std::collections::BTreeSet;
use super::graph::Heads;
use super::network::{PushOutcome, Remote};
use crate::system::history::shadow::HistoryRepo;
/// Reconciliation and complete live application must precede publication.
/// A merge that still changes this machine's saved tree needs another pull.
pub(crate) fn build(
repo: &HistoryRepo,
upstream: Option<&str>,
expected_local: Option<&str>,
accepted: &BTreeSet<String>,
allow_plaintext_history: bool,
) -> Result<Option<String>> {
let heads = Heads::read(repo)?;
if heads.local.as_deref() != expected_local {
bail!("local saved history changed while planning; reconcile again");
}
if heads.remote.as_deref() != upstream {
bail!("origin changed while preparing publication; reconcile again");
}
let Some(local) = &heads.local else {
return Ok(None);
};
if heads.remote.as_ref() == Some(local) {
return Ok(None);
}
let tree = repo.output_tree_of(local)?;
if let Some(remote) = &heads.remote
&& heads.base.as_ref() != Some(remote)
{
let (mut merged, mut conflicts) = repo.merge_tree(local, remote)?;
// Enrollment is a keyed inventory, not arbitrary JSON text. Git's
// line merge can conflict on independent additions or combine policy
// changes into invalid metadata. Validate its structured merge first.View on GitHub (pinned to 533346cc37)