jdx/mise · warning

another setup sync or pull is running; retry shortly

Error message

another setup sync or pull is running; retry shortly

What it means

mise serializes history sync/pull operations with a status lock file in the state directory. update_status's lock helper polls for the lock until a deadline (wait); if it cannot acquire the lock in time it aborts with this message rather than corrupting status by writing concurrently.

Solutions

  1. Wait a moment for the other operation to finish, then re-run the command — the message explicitly says retry shortly.
  2. Find the running `mise dot sync`/`mise dot pull` process (ps) and wait for it or terminate it if it is hung.
  3. If a stale lock is left behind by a crashed process, remove the stale lock file in the mise state directory once no sync process is running, then retry.

Example fix

// before: concurrent syncs
# terminal A: mise dot sync (running)
# terminal B: mise dot sync -> error: another setup sync or pull is running
// after: serialize
# terminal A: finish
# terminal B: retry
mise dot sync
Defensive patterns

Strategy: retry

Validate before calling

// probe the lock before running
if !try_status_lock(state_dir, Duration::ZERO) {
    eprintln!("another sync/pull is running; wait and retry");
    return;
}

Try / catch

loop {
    match sync() {
        Err(e) if e.to_string().contains("another setup sync or pull is running") => { sleep(POLL); continue; }
        other => break other,
    }
}

Prevention

When it happens

Trigger: Calling sync/pull/update_status while another `mise dot sync` or `mise dot pull` holds the status lock for longer than the configured wait deadline (long-running sync, hung process, or stale lock).

Common situations: Two terminals running sync/pull simultaneously; a scheduled sync overlapping an interactive one; a crashed sync that left a lock contended; a very slow sync (large repository, network stall) exceeding the wait window.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/0777b302ed532d05. Report an issue: GitHub.

Appendix: source

Thrown at src/system/history/sync/run.rs:518

pub(crate) fn update_status(
    state_dir: &Path,
    wait: Duration,
    mutate: impl FnOnce(&mut SyncStatus),
) -> Result<()> {
    let _lock = lock_wait(state_dir, wait)?;
    let mut status = read_status(state_dir)?;
    mutate(&mut status);
    write_status(state_dir, &status)
}

pub(crate) fn lock_wait(state_dir: &Path, wait: Duration) -> Result<fslock::LockFile> {
    let deadline = Instant::now() + wait;
    loop {
        if let Some(lock) = crate::lock_file::LockFile::at(&lock_path(state_dir)).try_lock()? {
            return Ok(lock);
        }
        if Instant::now() >= deadline {
            bail!("another setup sync or pull is running; retry shortly");
        }
        std::thread::sleep(STATUS_LOCK_POLL);
    }
}

/// A desktop notification for conflicts that newly need a decision, when
/// `history.notify` is on. Notify once per whole-setup pause, not per path.
/// Never blocks; a failure is only logged.
fn notify_new_conflicts(status: &mut SyncStatus) {
    notify_conflicts_with(
        status,
        crate::config::Settings::get().history.notify,
        crate::system::history::notify::send,
    );
}

fn notify_conflicts_with(status: &mut SyncStatus, enabled: bool, send: impl FnOnce(&str, &str)) {
    let current: BTreeSet<String> = status

View on GitHub (pinned to 533346cc37)