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

  1. Verify the `TrackedSet`/draft actually covers changed content so `attempt` has something to checkpoint.
  2. Inspect the returned `Outcome` variant (print it in the else branch) to see which no-op path was taken.
  3. Check recent changes to `Store::attempt` outcome classification (dedup, empty-draft short-circuit).
  4. 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

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.