{"record":{"id":"11d0fa5e44c22f8c","repo":"jdx/mise","slug":"checkpoint-did-not-finish-there-is-no-state-to","errorCode":null,"errorMessage":"checkpoint {} did not finish; there is no state to roll back to","messagePattern":"checkpoint (.+?) did not finish; there is no state to roll back to","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/replay.rs","lineNumber":1477,"sourceCode":"            return Ok(Some(entry.clone()));\n        }\n        // held content that differs, or a known absence while the path now\n        // exists, are both versions to return to\n        let differs = saved.is_some()\n            || matches!(\n                classify(&entry.checkpoint, &tree_path_to_display(&tree_path)),\n                PathState::Absent\n            );\n        if differs {\n            return Ok(Some(entry.clone()));\n        }\n    }\n    Ok(None)\n}\n\nfn refuse_unusable(entry: &Entry) -> Result<()> {\n    if entry.checkpoint.status() == Some(OperationStatus::Pending) {\n        bail!(\n            \"checkpoint {} did not finish; there is no state to roll back to\",\n            entry.id\n        );\n    }\n    if entry.checkpoint.tree.snapshot.is_none() {\n        bail!(\"checkpoint {} has no content snapshot\", entry.id);\n    }\n    if entry.checkpoint.schema_version > super::store::SCHEMA_VERSION {\n        bail!(\n            \"checkpoint {} was written by a newer mise (schema {})\",\n            entry.id,\n            entry.checkpoint.schema_version\n        );\n    }\n    Ok(())\n}\n\n/// Every path a checkpoint's coverage includes, as absolute paths.","sourceCodeStart":1459,"sourceCodeEnd":1495,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/history/replay.rs#L1459-L1495","documentation":"refuse_unusable() rejects checkpoints that cannot serve as a rollback source. A checkpoint still marked OperationStatus::Pending never finished recording, so there is no complete prior state to roll back to.","triggerScenarios":"`mise history` rollback targets an entry whose checkpoint.status() == Some(Pending) — e.g. a previous operation crashed or was killed mid-checkpoint.","commonSituations":"A terminated mise process (SIGKILL, power loss, OOM) left a dangling Pending checkpoint; user picks the newest history entry which is the incomplete one.","solutions":["Pick a different, completed checkpoint to roll back to (verify status is not Pending)","Re-run the original operation so it completes and produces a valid checkpoint","Clean up the stale Pending entry from history if the tooling permits, then retry"],"exampleFix":"// before\nmise history rollback <pending-id>   # errors\n// after\nmise history list   # choose a completed checkpoint\nmise history rollback <completed-id>","handlingStrategy":"validation","validationCode":"// only roll back to finished checkpoints\nlet target = entries.into_iter()\n    .find(|e| e.checkpoint.status() != Some(OperationStatus::Pending))\n    .expect(\"no completed checkpoint available\");","typeGuard":"fn is_rollbackable(e: &Entry) -> bool {\n    e.checkpoint.status() != Some(OperationStatus::Pending)\n        && e.checkpoint.tree.snapshot.is_some()\n}","tryCatchPattern":null,"preventionTips":["Avoid killing mise mid-operation (it leaves Pending checkpoints)","Verify checkpoint status before rolling back","Re-run interrupted operations so checkpoints complete"],"tags":["history","rollback","checkpoint","incomplete-state"],"backgroundTag":"invalid-state-transition","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"}