{"record":{"id":"39276f27256eacdd","repo":"jdx/mise","slug":"local-saved-history-changed-since-planning-nothin","errorCode":null,"errorMessage":"local saved history changed since planning; nothing was applied; run pull again","messagePattern":"local saved history changed since planning; nothing was applied; run pull again","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/scope.rs","lineNumber":238,"sourceCode":"                warn!(\"history: could not persist the capture label: {err:#}\");\n            }\n        }\n    }\n\n    /// The protective checkpoint this operation took, if any.\n    pub(crate) fn before(&self) -> Option<(u64, String)> {\n        self.0\n            .as_ref()\n            .and_then(|shared| lock_unpoisoned(shared).before.clone())\n    }\n\n    pub(crate) fn validate_starting_head(&self, expected: Option<&str>) -> Result<()> {\n        let Some(shared) = &self.0 else {\n            eyre::bail!(\"incoming application requires an active recovery operation\");\n        };\n        let writer = lock_unpoisoned(shared);\n        if writer.starting_head.as_deref() != expected {\n            eyre::bail!(\n                \"local saved history changed since planning; nothing was applied; run pull again\"\n            );\n        }\n        Ok(())\n    }\n\n    /// Retakes the protective checkpoint, replacing the earlier one, when\n    /// files changed between it and the verified plan.\n    pub(crate) fn recapture_before(&self, paths: &[PathBuf]) -> Result<()> {\n        let Some(shared) = &self.0 else {\n            return Ok(());\n        };\n        let mut writer = lock_unpoisoned(shared);\n        // held across the reservation, the capture, and the removal: the\n        // capture writes the index and a checkpoint ref, which a concurrent\n        // `mise bootstrap dotfiles save` must not interleave with\n        let _store_lock = writer.store.lock()?;\n        let previous = writer.before.take();","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/history/scope.rs#L220-L256","documentation":"validate_starting_head compares the head recorded when the plan was made against the current saved history head. If local saved history changed since planning, applying the plan could land on an unexpected base, so mise aborts with nothing applied and asks the user to pull again.","triggerScenarios":"writer.starting_head.as_deref() != expected: another history operation committed/rolled back between planning the incoming apply and executing it.","commonSituations":"Two machines or two shells sharing a state dir apply history concurrently; a local rollback or commit happened after `pull` started; stale plan replayed after local history edits.","solutions":["Run pull again so a fresh plan is generated against the current head","Avoid running other history operations concurrently with pull","If conflicts are frequent, serialize history operations across machines/shells"],"exampleFix":"// before\nmise pull   # plan created; local history changed meanwhile → error\n// after\nmise pull   # rerun: fresh plan against current head","handlingStrategy":"retry","validationCode":"let current_head = history.head();\nif Some(current_head.as_deref()) != planned_starting_head.as_deref() {\n    eprintln!(\"history changed since planning; replan (pull again)\");\n}","typeGuard":null,"tryCatchPattern":"match apply_incoming() {\n    Err(e) if e.to_string().contains(\"run pull again\") => pull_fresh_and_apply(),\n    other => other,\n}","preventionTips":["Do not run concurrent history operations while pulling","Re-pull after any local rollback/commit made mid-plan","One state dir per machine/shell workflow"],"tags":["history","concurrency","conflict","pull"],"backgroundTag":"conflicting-config-options","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}