jdx/mise · error

the annotated commit is not in the current history

Error message

the annotated commit is not in the current history

What it means

Before creating an annotation commit on the dotfile history, mise verifies that the target commit is reachable from HEAD by scanning `git rev-list <head>`. If the annotated commit is not in that list, the annotation would attach to a dangling or foreign commit, so the operation refuses. This prevents silently annotating history that a later rewrite or GC could orphan.

Source

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

    const ANNOTATION_TRAILER: &'static str = "Mise-Annotation: ";

    /// An annotation is an empty ordinary child commit, so labels and
    /// descriptions travel with the same ancestry without rewriting it.
    pub(crate) fn write_annotation(
        &self,
        target: &str,
        annotation: &super::store::Annotation,
    ) -> Result<()> {
        let head = self
            .ref_oid(Self::HISTORY_REF)?
            .ok_or_else(|| eyre::eyre!("no history to annotate"))?;
        if !self
            .rev_list(&head, usize::MAX)?
            .iter()
            .any(|commit| commit == target)
        {
            bail!("the annotated commit is not in the current history");
        }
        let message = format!(
            "annotate dotfile history\n\n{}{}",
            Self::ANNOTATION_TRAILER,
            serde_json::to_string(&(target, annotation))?
        );
        let commit = self.commit_tree(&self.output_tree_of(&head)?, vec![&head], &message)?;
        self.update_history_head(&commit, Some(&head))
    }

    pub(crate) fn read_annotation(
        &self,
        commit: &str,
    ) -> Result<Option<(String, super::store::Annotation)>> {
        let message = self.output_str(PlumbingCall::new(["show", "-s", "--format=%B", commit]))?;
        message
            .lines()
            .rev()

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Run `mise dot log` (or inspect the shadow repo's `git log`) to find commit hashes valid in the current history.
  2. Re-copy the target commit hash from the current history and retry the annotate command.
  3. If the commit is genuinely missing, re-sync or restore the dotfile history so the commit is reachable from HEAD again.
  4. Verify HEAD hasn't been rewritten: `git rev-list <head> | grep <target>` inside the shadow repo.

Example fix

// before: annotating a stale hash
annotate("a1b2c3d...") // not in current history
// after: resolve a fresh hash from the live log first
let target = store.resolve_checkpoint_prefix(&spec)?;
annotate(target)
Defensive patterns

Strategy: validation

Validate before calling

let reachable = history.rev_list(head, usize::MAX)?;
if !reachable.iter().any(|c| c == target) {
    eprintln!("{target} is not in current history; pick from `mise dot log`");
}

Try / catch

match history.annotate(target, note) {
    Ok(()) => {},
    Err(e) if e.to_string().contains("not in the current history") => {
        eprintln!("stale commit hash; re-resolve from `mise dot log`");
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling the annotate API with a commit hash/ref that exists but is not an ancestor of the current HEAD — e.g. the hash came from an older history that was rewritten, force-pushed, or reset.

Common situations: A user annotates a checkpoint ID saved in a shell alias or notes file after the dotfile history was reset or rebuilt; history was truncated by a `pull --force` or manual `git reset` in the shadow repo.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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