{"record":{"id":"0eaa3de28270ed6c","repo":"GitoxideLabs/gitoxide","slug":"undo-metadata-must-start-with-undo","errorCode":null,"errorMessage":"undo metadata must start with [undo]","messagePattern":"undo metadata must start with \\[undo\\]","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-tix/src/edit/undo.rs","lineNumber":599,"sourceCode":"}\n\nfn encode_state(state: &State) -> BString {\n    match state {\n        State::Missing => \"missing\".into(),\n        State::Object(id) => format!(\"object:{id}\").into(),\n        State::Symbolic(name) => {\n            let mut value = BString::from(\"symbolic:\");\n            value.extend_from_slice(name.as_bstr());\n            value\n        }\n    }\n}\n\nfn parse_config(repo: &gix::Repository, body: &BStr) -> Result<Vec<RefChange>> {\n    let config = File::try_from(body).context(\"could not parse undo metadata as Git config\")?;\n    let mut sections = config.sections();\n    let undo = sections.next().context(\"undo metadata has no version section\")?;\n    ensure!(\n        undo.header().name() == b\"undo\" && undo.header().subsection_name().is_none(),\n        \"undo metadata must start with [undo]\"\n    );\n    ensure_exact_keys(&undo, &[\"version\"])?;\n    ensure!(\n        undo.value(\"version\").as_ref().map(|value| value.as_slice()) == Some(VERSION.as_bytes()),\n        \"unsupported undo metadata version\"\n    );\n\n    let mut changes = Vec::new();\n    let mut previous_name: Option<FullName> = None;\n    for section in sections {\n        ensure!(\n            section.header().name() == b\"ref\",\n            \"undo metadata contains an unknown section\"\n        );\n        let subsection = section\n            .header()","sourceCodeStart":581,"sourceCodeEnd":617,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-tix/src/edit/undo.rs#L581-L617","documentation":"Undo queue commits store their metadata as a Git config blob inside the commit. `parse_config` requires the very first config section to be `[undo]` with no subsection — this anchors and versions the metadata format. A commit whose config blob starts with any other section (or a subsectioned `[undo \"x\"]`) is not a valid undo-metadata commit, so this error is raised.","triggerScenarios":"`parse_commit` -> `parse_config` when the referenced queue commit's config body has a different leading section, e.g. queue refs pointing at ordinary commits or hand-built queue commits with the wrong config layout.","commonSituations":"Manually crafted queue commits; queue refs pointing at unrelated commits (e.g. after ref juggling or restore from backup); third-party tools writing to the queue refs with their own format.","solutions":["Check what the queue refs point at (`git cat-file -p <tip>`) — if they point at non-undo commits, reset the queue refs to valid undo commits or discard the queue.","Regenerate the queue via the library's record/reset APIs instead of writing queue commits by hand.","Restore the queue from a backup where the metadata was valid."],"exampleFix":"// before: hand-built queue commit body\n\"[core]\\n\\tfoo = bar\\n\"\n// after: metadata must open with the [undo] version section\n\"[undo]\\n\\tversion = 1\\n\" // plus the recorded ref changes","handlingStrategy":"validation","validationCode":"// verify queue refs point at genuine undo-metadata commits before undo/redo\nlet commit = repo.find_object(tip_id)?;\nlet body = extract_config_body(&commit);\nlet ok = body.starts_with(b\"[undo]\");\nif !ok { anyhow::bail!(\"queue tip is not an undo-metadata commit; reset the queue\"); }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Create queue commits only through the library's record API.","Never point queue refs at arbitrary commits.","After restoring a repo from backup, sanity-check queue commit contents before undo."],"tags":["git","undo-queue","metadata","config-format"],"backgroundTag":"schema-validation-failed","analyzedSha":"e73179060badf27222d790981fac3f84c1830a7e","analyzedAt":"2026-09-08T11:26:50.865Z","contentChangedAt":"2026-09-08T11:26:50.865Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}