jdx/mise · error
checkpoint {} has no content snapshot
Error message
checkpoint {} has no content snapshot What it means
Planning a replay requires the checkpoint's content snapshot (checkpoint.tree.snapshot) to compute file-level diffs. If the referenced checkpoint entry has no snapshot, planning cannot proceed and mise throws this error with the checkpoint id.
Source
Thrown at src/system/history/replay.rs:903
/// The plan for every selected path of every target.
fn repository_path(repo: &HistoryRepo, tree: &str, path: &Path) -> Result<String> {
if let Some(manifest) = super::manifest::Manifest::read(repo, tree)? {
let tracked = manifest.tracking()?;
if let Some(entry) = tracked.entry_for(&normalize_target(path)) {
return entry.tree_path(&normalize_target(path));
}
}
Ok(display_to_tree_path(&path.to_string_lossy()))
}
fn plan(repo: &HistoryRepo, exec: &Execution, live: &str) -> Result<Vec<Step>> {
let force = exec.force;
let mut steps = vec![];
for target in &exec.targets {
let checkpoint = &target.entry.checkpoint;
let Some(snapshot) = &checkpoint.tree.snapshot else {
bail!("checkpoint {} has no content snapshot", target.entry.id);
};
for path in &target.paths {
let tree_path = repository_path(repo, live, path)?;
let mut files: BTreeSet<String> = BTreeSet::new();
let mut live_files: BTreeSet<String> = BTreeSet::new();
let mut snapshot_files: BTreeSet<String> = BTreeSet::new();
// nested repositories in either tree: what is inside one is its
// own, never written into or removed by a rollback
let mut gitlinks: BTreeSet<String> = BTreeSet::new();
for tree in [snapshot.as_str(), live] {
let selected = repository_path(repo, tree, path)?;
match repo.object_at(tree, &selected)? {
Some((mode, _)) if mode == "040000" => {
for entry in repo.ls_tree(&format!("{tree}:{selected}"))? {
let file = format!("{tree_path}/{}", entry.path);
if entry.mode == "160000" {
gitlinks.insert(file.clone());
}View on GitHub (pinned to afd2eddd3a)
Solutions
- List checkpoints (`mise history`) and target one that includes a content snapshot
- Use `refuse_unusable`-style checks: pick a checkpoint with a non-pending status and a snapshot
- If the checkpoint should have a snapshot, the store may be corrupted — recreate/re-record the checkpoint
Defensive patterns
Strategy: validation
Validate before calling
// select only checkpoints that have a content snapshot
let usable: Vec<_> = entries.into_iter()
.filter(|e| e.checkpoint.tree.snapshot.is_some())
.collect(); Type guard
fn has_snapshot(e: &Entry) -> bool {
e.checkpoint.tree.snapshot.is_some()
} Prevention
- Only target checkpoints that recorded file contents
- Check history listings for snapshot info before replaying
- Treat snapshotless checkpoints as metadata-only
When it happens
Trigger: `mise history` replay/rollback targets a checkpoint entry whose tree.snapshot is None — plan() iterates exec.targets and bails on the first snapshotless entry.
Common situations: Targeting an operation checkpoint that only recorded metadata (e.g. a command that never captured file contents); a truncated or partially-written checkpoint; internal checkpoints that don't snapshot trees.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 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 {} did not finish; there is no state to roll back
- no baseline
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/6ac1fd4f239cf622.
Report an issue: GitHub.