{"record":{"id":"0777b302ed532d05","repo":"jdx/mise","slug":"another-setup-sync-or-pull-is-running-retry-short","errorCode":null,"errorMessage":"another setup sync or pull is running; retry shortly","messagePattern":"another setup sync or pull is running; retry shortly","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/sync/run.rs","lineNumber":495,"sourceCode":"pub(crate) fn update_status(\n    state_dir: &Path,\n    wait: Duration,\n    mutate: impl FnOnce(&mut SyncStatus),\n) -> Result<()> {\n    let _lock = lock_wait(state_dir, wait)?;\n    let mut status = read_status(state_dir)?;\n    mutate(&mut status);\n    write_status(state_dir, &status)\n}\n\npub(crate) fn lock_wait(state_dir: &Path, wait: Duration) -> Result<fslock::LockFile> {\n    let deadline = Instant::now() + wait;\n    loop {\n        if let Some(lock) = crate::lock_file::LockFile::new(&lock_path(state_dir)).try_lock()? {\n            return Ok(lock);\n        }\n        if Instant::now() >= deadline {\n            bail!(\"another setup sync or pull is running; retry shortly\");\n        }\n        std::thread::sleep(STATUS_LOCK_POLL);\n    }\n}\n\n/// A desktop notification for conflicts that newly need a decision, when\n/// `history.notify` is on. Notify once per whole-setup pause, not per path.\n/// Never blocks; a failure is only logged.\nfn notify_new_conflicts(status: &mut SyncStatus) {\n    notify_conflicts_with(\n        status,\n        crate::config::Settings::get().history.notify,\n        crate::system::history::notify::send,\n    );\n}\n\nfn notify_conflicts_with(status: &mut SyncStatus, enabled: bool, send: impl FnOnce(&str, &str)) {\n    let current: BTreeSet<String> = status","sourceCodeStart":477,"sourceCodeEnd":513,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/history/sync/run.rs#L477-L513","documentation":"The sync/pull flow serializes through a status lock file in the state directory. `lock_wait` polls `try_lock` until a deadline (`wait`); if the lock is still held when the deadline expires, it aborts with this error instead of corrupting shared status. No changes were made; the concurrent operation still owns the lock.","triggerScenarios":"Running `mise bootstrap dotfiles sync` or `pull` while another sync/pull process already holds the status lock for longer than the wait deadline — e.g. two terminals, a scheduled background sync overlapping an interactive one, or a crashed process that leaked the lock.","commonSituations":"Cron/systemd-triggered periodic sync running at the same time as a manual pull; long-running sync on a slow network; stale lock left by a killed process.","solutions":["Retry the command shortly, once the other sync/pull finishes","Find and wait for/stop the concurrent process (`pgrep -af 'mise bootstrap dotfiles'`); if a process crashed and leaked the lock, remove the stale lock file in the mise state directory","Serialize automatic syncs (cron intervals) so they don't overlap interactive use"],"exampleFix":"// before\n$ mise bootstrap dotfiles pull &\n$ mise bootstrap dotfiles sync\nerror: another setup sync or pull is running; retry shortly\n\n// after\n$ mise bootstrap dotfiles pull\n$ mise bootstrap dotfiles sync   # run sequentially","handlingStrategy":"retry","validationCode":"pgrep -af 'mise bootstrap dotfiles' || mise bootstrap dotfiles sync","typeGuard":null,"tryCatchPattern":"catch (e) { if (String(e).includes('another setup sync or pull is running')) { await sleep(2000); return retrySync(); } throw e; }","preventionTips":["Run sync/pull commands sequentially, not in parallel shells","Space out scheduled (cron) syncs and avoid overlapping with interactive use","Clean up stale locks after a crashed sync process"],"tags":["concurrency","lock","sync","contention"],"backgroundTag":"address-already-in-use","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"}