jdx/mise · error
expected a checkpoint
Error message
expected a checkpoint
What it means
A test panic in src/system/history/checkpoint.rs asserting that `Store::attempt` returned `Outcome::Created` (a new checkpoint). Any other `Outcome` variant (e.g. `Outcome::Identical`, `Noop`, or an error-mapped outcome) reaches the else branch and panics with 'expected a checkpoint'. It means the history store did not create a checkpoint where the test requires one.
Source
Thrown at src/system/history/checkpoint.rs:1171
store.unavailable = Some("Git is unavailable".into());
let mut draft = Draft::new(Trigger::Agent);
draft.description = Some("labeled operation".into());
assert!(matches!(
store.attempt(&TrackedSet::default(), draft)?,
Outcome::Unavailable(_)
));
assert!(store::load_index_in(temp.path())?.entries.is_empty());
Ok(())
}
#[test]
fn numeric_commit_prefixes_cannot_silently_select_another_checkpoint() -> Result<()> {
let temp = tempfile::tempdir()?;
let store = Store::open_in(temp.path())?;
let Outcome::Created(mut first) =
store.attempt(&TrackedSet::default(), Draft::new(Trigger::Agent))?
else {
panic!("expected a checkpoint");
};
first.id = 42;
first.checkpoint.uuid = "123abc".into();
let mut second = first.clone();
second.id = 123;
second.checkpoint.uuid = "abcdef".into();
let entries = vec![*first, *second];
assert!(store::resolve_ref("12", &entries).is_err());
assert_eq!(store::resolve_ref("42", &entries)?, 42);
assert_eq!(store::resolve_ref("123", &entries)?, 123);
assert_eq!(store::resolve_ref("commit:12", &entries)?, 42);
assert_eq!(store::resolve_ref("commit:123", &entries)?, 42);
assert!(store::resolve_ref("commit:", &entries).is_err());
assert!(store::resolve_ref("", &entries).is_err());
assert!(store::resolve_ref("1234567890123456789012345678901234567890", &entries).is_err());
assert_eq!(store::resolve_ref("123abc", &entries)?, 42);
Ok(())
}View on GitHub (pinned to afd2eddd3a)
Solutions
- Verify the `TrackedSet`/draft actually covers changed content so `attempt` has something to checkpoint.
- Inspect the returned `Outcome` variant (print it in the else branch) to see which no-op path was taken.
- Check recent changes to `Store::attempt` outcome classification (dedup, empty-draft short-circuit).
- Seed the store with real file changes before the first attempt if a baseline is required.
Example fix
// before
let Outcome::Created(mut first) =
store.attempt(&TrackedSet::default(), Draft::new(Trigger::Agent))?
else {
panic!("expected a checkpoint");
};
// after
let outcome = store.attempt(&TrackedSet::default(), Draft::new(Trigger::Agent))?;
let Outcome::Created(mut first) = outcome else {
panic!("expected a checkpoint, got {outcome:?}");
}; Defensive patterns
Strategy: type-guard
Validate before calling
// rust
if tracked.is_empty() {
return Err("tracked set is empty; attempt cannot create a checkpoint");
} Type guard
fn created(outcome: Outcome) -> Option<Created> {
match outcome {
Outcome::Created(c) => Some(c),
_ => None,
}
} Try / catch
// rust
let outcome = store.attempt(&tracked, draft)?;
let Outcome::Created(cp) = outcome else {
return Err(anyhow!("expected a checkpoint, got {outcome:?}"));
}; Prevention
- Ensure drafts cover actual changes before calling attempt.
- Match exhaustively on Outcome instead of assuming Created.
- Log unexpected outcome variants in tests for faster diagnosis.
- Track regressions in attempt short-circuit paths with dedicated tests.
When it happens
Trigger: Calling `store.attempt(&TrackedSet::default(), Draft::new(Trigger::Agent))` on a fresh store and getting a non-`Created` outcome — e.g. the tracked set is empty so nothing is considered changed, or attempt logic classifies the draft as a no-op.
Common situations: Default `TrackedSet` matching no files so attempt returns a no-op outcome; changes to checkpoint deduplication/skip logic; tests refactored so a prior checkpoint already covers the draft, making `attempt` return `Identical` instead of `Created`.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/9bd75dea98b6fe8b.
Report an issue: GitHub.