jdx/mise · error

checkpoint is still running or was interrupted; nothing to…

Error message

checkpoint {} is still running or was interrupted; nothing to undo

What it means

A checkpoint whose operation status is `Pending` is either still executing or was interrupted mid-run, so its before/after state is not settled. Undo refuses to restore from an in-flight or half-finished operation to avoid corrupting files.

Solutions

  1. Wait for any concurrently running mise operation to finish, then retry undo
  2. If the operation was interrupted, let the failed-operation recovery path handle it or re-run the original operation so it completes and updates its status
  3. Inspect history status with `mise dot history` and choose a completed (non-Pending) checkpoint to undo
Defensive patterns

Strategy: retry

Validate before calling

const entry = await history.find(e => e.operation?.status === 'pending');
if (entry) await waitForOperationToSettle(entry.id);

Try / catch

try {
  await mise.dot.undo();
} catch (e) {
  if (/still running or was interrupted/.test(e.message)) {
    // wait / re-run the original operation, then retry once
  }
}

Prevention

When it happens

Trigger: Calling `mise dot undo` on a checkpoint whose `OperationStatus` is `Pending` — an operation currently running in another process, or one killed before its status was finalized.

Common situations: Two `mise` processes touching dotfiles concurrently; a previous operation crashed (SIGKILL, terminal closed, power loss) leaving status stuck at Pending; user immediately retries after interrupting an operation.

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@533346cc37 (2026-09-17). Data as JSON: /api/errors/1bf6fe698c7a85ee. Report an issue: GitHub.

Appendix: source

Thrown at src/system/history/replay.rs:276

        None => entries
            .iter()
            .rev()
            .find(|entry| {
                entry.checkpoint.operation.as_ref().is_some_and(|op| {
                    op.status != OperationStatus::Pending
                        && op.before.is_some()
                        && !op.affected.is_empty()
                }) && !undone.contains(&entry.checkpoint.uuid)
            })
            .cloned()
            .ok_or_else(|| eyre::eyre!("nothing to undo: no tracked-file operation is left"))?,
    };
    let Some(op) = operation.checkpoint.operation.clone() else {
        bail!("checkpoint {} is not an operation", operation.id);
    };
    // Undo restores tracked files only, never package or service state.
    if op.status == OperationStatus::Pending {
        bail!(
            "checkpoint {} is still running or was interrupted; nothing to undo",
            operation.id
        );
    }
    if op.status == OperationStatus::Failed && !op.affected.is_empty() {
        info!(
            "history: operation {} failed midway; reversing the {} path(s) it changed",
            operation.id,
            op.affected.len()
        );
    }
    let Some(before_uuid) = &op.before else {
        bail!(
            "checkpoint {} has no protective checkpoint to undo from",
            operation.id
        );
    };
    let Some(before) = entries

View on GitHub (pinned to 533346cc37)