jdx/mise · error

this store uses the old unreleased checkpoint format; use a

Error message

this store uses the old unreleased checkpoint format; use a separate MISE_STATE_DIR for the new history format; existing data has not been changed

What it means

When opening the history store, open_or_init_in checks for refs under refs/checkpoints/, which only the old, never-released checkpoint format created. If such refs exist, the store predates the new history format; mise refuses to touch it so existing data is preserved, and directs the user to isolate it with a separate MISE_STATE_DIR.

Source

Thrown at src/system/history/shadow.rs:182

    /// Opens the repository, creating it on first use. `Ok(None)` means no
    /// git binary mise is willing to run is available.
    pub(crate) fn open_or_init_in(state_dir: &Path) -> Result<Option<Self>> {
        if crate::git::plumbing_binary().is_none() {
            return Ok(None);
        }
        let git = GitPlumbing::new(Self::path_in(state_dir));
        git.init_bare()
            .wrap_err_with(|| format!("initializing {}", display_path(git.git_dir())))?;
        // the binary may exist and still be unusable (a stub, a broken
        // install): probe it once so callers can say capture is unavailable
        git.run(PlumbingCall::new(["rev-parse", "--is-bare-repository"]))
            .wrap_err_with(|| format!("opening {}", display_path(git.git_dir())))?;
        let repo = Self {
            git,
            transient: Default::default(),
        };
        if !repo.list_refs("refs/checkpoints/")?.is_empty() {
            bail!(
                "this store uses the old unreleased checkpoint format; use a separate MISE_STATE_DIR for the new history format; existing data has not been changed"
            );
        }
        Ok(Some(repo))
    }

    pub(crate) fn dir(&self) -> &Path {
        self.git.git_dir()
    }

    pub(crate) fn capture_tracked(
        &self,
        walk: &super::tracked::Walk,
        recipient_strings: &[String],
        interactive: bool,
    ) -> Result<CaptureResult> {
        let mut manifest = walk.manifest.clone();
        manifest.recipients = recipient_strings.to_vec();

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Set MISE_STATE_DIR to a fresh location for the new history format, as the message advises
  2. If the old data is dispensable, delete/move the old state dir (archives refs) so mise can init a clean store
  3. Export or manually salvage anything needed from the old store before abandoning it; the error path does not modify it

Example fix

// before
export MISE_STATE_DIR=~/.local/state/mise   # contains old refs/checkpoints/
// after
export MISE_STATE_DIR=~/.local/state/mise-new && mise history init
Defensive patterns

Strategy: fallback

Validate before calling

// before running new mise against a state dir:
if git_for_each_ref(dir, "refs/checkpoints/").next().is_some() {
    eprintln!("legacy store detected; point MISE_STATE_DIR elsewhere");
}

Try / catch

match open_store(state_dir) {
    Err(e) if e.to_string().contains("old unreleased checkpoint format") => {
        set_mise_state_dir(fresh_dir()); retry();
    }
    other => other,
}

Prevention

When it happens

Trigger: Running current mise against a MISE_STATE_DIR previously used by an unreleased mise build that wrote refs/checkpoints/ into its embedded git store.

Common situations: Upgrading from a development/experimental mise version to the released history implementation; sharing a state dir across old dev builds and new releases; CI caches seeded by an old build.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/58931a4612c44c41. Report an issue: GitHub.