{"record":{"id":"1bf6fe698c7a85ee","repo":"jdx/mise","slug":"checkpoint-is-still-running-or-was-interrupted","errorCode":null,"errorMessage":"checkpoint {} is still running or was interrupted; nothing to undo","messagePattern":"checkpoint (.+?) is still running or was interrupted; nothing to undo","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/replay.rs","lineNumber":276,"sourceCode":"        None => entries\n            .iter()\n            .rev()\n            .find(|entry| {\n                entry.checkpoint.operation.as_ref().is_some_and(|op| {\n                    op.status != OperationStatus::Pending\n                        && op.before.is_some()\n                        && !op.affected.is_empty()\n                }) && !undone.contains(&entry.checkpoint.uuid)\n            })\n            .cloned()\n            .ok_or_else(|| eyre::eyre!(\"nothing to undo: no tracked-file operation is left\"))?,\n    };\n    let Some(op) = operation.checkpoint.operation.clone() else {\n        bail!(\"checkpoint {} is not an operation\", operation.id);\n    };\n    // Undo restores tracked files only, never package or service state.\n    if op.status == OperationStatus::Pending {\n        bail!(\n            \"checkpoint {} is still running or was interrupted; nothing to undo\",\n            operation.id\n        );\n    }\n    if op.status == OperationStatus::Failed && !op.affected.is_empty() {\n        info!(\n            \"history: operation {} failed midway; reversing the {} path(s) it changed\",\n            operation.id,\n            op.affected.len()\n        );\n    }\n    let Some(before_uuid) = &op.before else {\n        bail!(\n            \"checkpoint {} has no protective checkpoint to undo from\",\n            operation.id\n        );\n    };\n    let Some(before) = entries","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/history/replay.rs#L258-L294","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Wait for any concurrently running mise operation to finish, then retry undo","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","Inspect history status with `mise dot history` and choose a completed (non-Pending) checkpoint to undo"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"const entry = await history.find(e => e.operation?.status === 'pending');\nif (entry) await waitForOperationToSettle(entry.id);","typeGuard":null,"tryCatchPattern":"try {\n  await mise.dot.undo();\n} catch (e) {\n  if (/still running or was interrupted/.test(e.message)) {\n    // wait / re-run the original operation, then retry once\n  }\n}","preventionTips":["Avoid running multiple mise dot operations concurrently","Let interrupted operations finish or explicitly recover them before undo","Check operation status in `mise dot history` before undoing"],"tags":["dotfiles","undo","state"],"backgroundTag":"invalid-state-transition","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}