{"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/533346cc374382b41ec5ff70536252b2e96e725c/src/system/history/replay.rs#L1459-L1495","documentation":"Rollback refuses checkpoints that are still marked Pending: their recorded state is not final, so rolling back to them would restore an indeterminate state. The checkpoint id is valid but unusable until the operation that created it completes.","triggerScenarios":"`mise history rollback <id>` where Entry.checkpoint.status() == Some(OperationStatus::Pending) in refuse_unusable.","commonSituations":"A previous mise operation (install, task run with checkpointing) crashed or is still running; stale Pending entries left after a killed process.","solutions":["Wait for the operation that created the checkpoint to finish, then retry the rollback.","If the creating process is dead, remove/clean the stale checkpoint from the history store and use an earlier completed checkpoint.","Use a different, completed checkpoint id as the rollback target."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"mise history list | jq 'select(.id == \"<id>\") | .status'  # must not be \"pending\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Roll back only to checkpoints with a completed status.","Clean stale entries after crashed operations.","Avoid killing mise processes that are checkpointing."],"tags":["history","checkpoint","pending-state","rollback"],"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"}