{"record":{"id":"7a0be7c054beac4f","repo":"GitoxideLabs/gitoxide","slug":"undo-metadata-has-missing-repeated-or-unknown-ke","errorCode":null,"errorMessage":"undo metadata has missing, repeated, or unknown keys","messagePattern":"undo metadata has missing, repeated, or unknown keys","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-tix/src/edit/undo.rs","lineNumber":642,"sourceCode":"                previous < &name,\n                \"undo reference sections are duplicated or out of order\"\n            );\n        }\n        previous_name = Some(name.clone());\n        ensure_exact_keys(&section, &[\"before\", \"after\"])?;\n        let before = section.value(\"before\").context(\"an undo ref has no before-state\")?;\n        let before = parse_state(repo, before.as_bstr())?;\n        let after = section.value(\"after\").context(\"an undo ref has no after-state\")?;\n        let after = parse_state(repo, after.as_bstr())?;\n        ensure!(before != after, \"an undo ref does not change\");\n        changes.push(RefChange { name, before, after });\n    }\n    Ok(changes)\n}\n\nfn ensure_exact_keys(section: &gix::config::file::SectionRef<'_>, expected: &[&str]) -> Result<()> {\n    let actual: Vec<_> = section.value_names().collect();\n    ensure!(\n        actual == expected,\n        \"undo metadata has missing, repeated, or unknown keys\"\n    );\n    Ok(())\n}\n\nfn parse_state(repo: &gix::Repository, value: &BStr) -> Result<State> {\n    if value == b\"missing\" {\n        return Ok(State::Missing);\n    }\n    if let Some(hex) = value.strip_prefix(b\"object:\") {\n        let id = ObjectId::from_hex(hex).context(\"an undo object ID is invalid\")?;\n        ensure!(\n            id.kind() == repo.object_hash(),\n            \"an undo object ID uses the wrong hash kind\"\n        );\n        return Ok(State::Object(id));\n    }","sourceCodeStart":624,"sourceCodeEnd":660,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-tix/src/edit/undo.rs#L624-L660","documentation":"`ensure_exact_keys` compares the section's actual value names against the exact expected list and rejects any mismatch: a missing key, a duplicated key, or an extra unknown key. This enforces a strict schema for undo metadata sections so parsing downstream can assume every expected key exists exactly once.","triggerScenarios":"`parse_config` calls `ensure_exact_keys(&section, &[\"before\", \"after\"])` (undo.rs:642) on a section that lacks one of the keys, repeats a key, or contains additional keys such as a typo (`befor`) or a comment-like unknown entry.","commonSituations":"Hand-editing the undo metadata and misspelling `before`/`after`; an older or newer tool version writing extra fields; accidentally duplicating a key when editing; copy-pasting sections and leaving stray keys behind.","solutions":["Make each section contain exactly the expected keys, each once: `before` and `after`, with no extras.","Fix typos in key names (`befor` -> `before`).","Remove obsolete/unknown keys added by other tool versions.","Regenerate the undo metadata with the writing tool rather than hand-editing; if new keys are legitimate, update the expected list in `ensure_exact_keys`."],"exampleFix":"// before\n[undo-ref \"refs/heads/main\"]\n\tbefor = object:1a2b3c...\n\tafter = object:9f8e7d...\n\tcomment = note\n// after\n[undo-ref \"refs/heads/main\"]\n\tbefore = object:1a2b3c...\n\tafter = object:9f8e7d...","handlingStrategy":"validation","validationCode":"fn section_keys_valid(section: &gix::config::file::SectionRef<'_>) -> bool {\n    let names: Vec<_> = section.value_names().collect();\n    names == [\"before\", \"after\"]\n}","typeGuard":null,"tryCatchPattern":"match parse_undo_metadata(&repo, &text) {\n    Err(e) if e.to_string().contains(\"undo metadata has missing, repeated, or unknown keys\") => {\n        eprintln!(\"Each section needs exactly one `before` and one `after` key, no extras\");\n    }\n    res => res?,\n}","preventionTips":["Use a writer function (not hand edits) to emit undo sections","Check key spelling: only `before` and `after` are accepted","Diff metadata files against a known-good sample before use","When adding fields, update both writer and `ensure_exact_keys` in the same change"],"tags":["schema-validation","config-parse","undo","keys"],"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"}