{"record":{"id":"c381e3db38c4b155","repo":"jdx/mise","slug":"the-annotated-commit-is-not-in-the-current-history","errorCode":null,"errorMessage":"the annotated commit is not in the current history","messagePattern":"the annotated commit is not in the current history","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/shadow.rs","lineNumber":1402,"sourceCode":"\n    const ANNOTATION_TRAILER: &'static str = \"Mise-Annotation: \";\n\n    /// An annotation is an empty ordinary child commit, so labels and\n    /// descriptions travel with the same ancestry without rewriting it.\n    pub(crate) fn write_annotation(\n        &self,\n        target: &str,\n        annotation: &super::store::Annotation,\n    ) -> Result<()> {\n        let head = self\n            .ref_oid(Self::HISTORY_REF)?\n            .ok_or_else(|| eyre::eyre!(\"no history to annotate\"))?;\n        if !self\n            .rev_list(&head, usize::MAX)?\n            .iter()\n            .any(|commit| commit == target)\n        {\n            bail!(\"the annotated commit is not in the current history\");\n        }\n        let message = format!(\n            \"annotate dotfile history\\n\\n{}{}\",\n            Self::ANNOTATION_TRAILER,\n            serde_json::to_string(&(target, annotation))?\n        );\n        let commit = self.commit_tree(&self.output_tree_of(&head)?, vec![&head], &message)?;\n        self.update_history_head(&commit, Some(&head))\n    }\n\n    pub(crate) fn read_annotation(\n        &self,\n        commit: &str,\n    ) -> Result<Option<(String, super::store::Annotation)>> {\n        let message = self.output_str(PlumbingCall::new([\"show\", \"-s\", \"--format=%B\", commit]))?;\n        message\n            .lines()\n            .rev()","sourceCodeStart":1384,"sourceCodeEnd":1420,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/history/shadow.rs#L1384-L1420","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Run `mise dot log` (or inspect the shadow repo's `git log`) to find commit hashes valid in the current history.","Re-copy the target commit hash from the current history and retry the annotate command.","If the commit is genuinely missing, re-sync or restore the dotfile history so the commit is reachable from HEAD again.","Verify HEAD hasn't been rewritten: `git rev-list <head> | grep <target>` inside the shadow repo."],"exampleFix":"// before: annotating a stale hash\nannotate(\"a1b2c3d...\") // not in current history\n// after: resolve a fresh hash from the live log first\nlet target = store.resolve_checkpoint_prefix(&spec)?;\nannotate(target)","handlingStrategy":"validation","validationCode":"let reachable = history.rev_list(head, usize::MAX)?;\nif !reachable.iter().any(|c| c == target) {\n    eprintln!(\"{target} is not in current history; pick from `mise dot log`\");\n}","typeGuard":null,"tryCatchPattern":"match history.annotate(target, note) {\n    Ok(()) => {},\n    Err(e) if e.to_string().contains(\"not in the current history\") => {\n        eprintln!(\"stale commit hash; re-resolve from `mise dot log`\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Always copy annotate targets from a fresh `mise dot log`","Re-resolve hashes after any history reset or force-pull","Avoid annotating by memory or stale shell history"],"tags":["git","dotfiles","history","commit-not-found"],"backgroundTag":"record-not-found","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}