jdx/mise · error
checkpoint {} did not finish; there is no state to roll back
Error message
checkpoint {} did not finish; there is no state to roll back to What it means
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.
Source
Thrown at src/system/history/replay.rs:1477
return Ok(Some(entry.clone()));
}
// held content that differs, or a known absence while the path now
// exists, are both versions to return to
let differs = saved.is_some()
|| matches!(
classify(&entry.checkpoint, &tree_path_to_display(&tree_path)),
PathState::Absent
);
if differs {
return Ok(Some(entry.clone()));
}
}
Ok(None)
}
fn refuse_unusable(entry: &Entry) -> Result<()> {
if entry.checkpoint.status() == Some(OperationStatus::Pending) {
bail!(
"checkpoint {} did not finish; there is no state to roll back to",
entry.id
);
}
if entry.checkpoint.tree.snapshot.is_none() {
bail!("checkpoint {} has no content snapshot", entry.id);
}
if entry.checkpoint.schema_version > super::store::SCHEMA_VERSION {
bail!(
"checkpoint {} was written by a newer mise (schema {})",
entry.id,
entry.checkpoint.schema_version
);
}
Ok(())
}
/// Every path a checkpoint's coverage includes, as absolute paths.View on GitHub (pinned to afd2eddd3a)
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
Example fix
// before mise history rollback <pending-id> # errors // after mise history list # choose a completed checkpoint mise history rollback <completed-id>
Defensive patterns
Strategy: validation
Validate before calling
// only roll back to finished checkpoints
let target = entries.into_iter()
.find(|e| e.checkpoint.status() != Some(OperationStatus::Pending))
.expect("no completed checkpoint available"); Type guard
fn is_rollbackable(e: &Entry) -> bool {
e.checkpoint.status() != Some(OperationStatus::Pending)
&& e.checkpoint.tree.snapshot.is_some()
} Prevention
- Avoid killing mise mid-operation (it leaves Pending checkpoints)
- Verify checkpoint status before rolling back
- Re-run interrupted operations so checkpoints complete
When it happens
Trigger: `mise history` rollback targets an entry whose checkpoint.status() == Some(Pending) — e.g. a previous operation crashed or was killed mid-checkpoint.
Common situations: A terminated mise process (SIGKILL, power loss, OOM) left a dangling Pending checkpoint; user picks the newest history entry which is the incomplete one.
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
- expected a checkpoint
- cannot retain an unreadable plaintext version of newly encry
- no protective checkpoint could be taken; nothing was changed
- checkpoint {} has no content snapshot
- no baseline
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/11d0fa5e44c22f8c.
Report an issue: GitHub.