GitoxideLabs/gitoxide · error
undo metadata must start with [undo]
Error message
undo metadata must start with [undo]
What it means
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.
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.
Example fix
// before: hand-built queue commit body "[core]\n\tfoo = bar\n" // after: metadata must open with the [undo] version section "[undo]\n\tversion = 1\n" // plus the recorded ref changes
Defensive patterns
Strategy: validation
Validate before calling
// verify queue refs point at genuine undo-metadata commits before undo/redo
let commit = repo.find_object(tip_id)?;
let body = extract_config_body(&commit);
let ok = body.starts_with(b"[undo]");
if !ok { anyhow::bail!("queue tip is not an undo-metadata commit; reset the queue"); } Prevention
- 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.
When it happens
Trigger: `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.
Common situations: 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.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- unsupported undo metadata version
- the undo queue cannot record itself
- successive changes to
- Tried to use as tree, but was
- Tried to use as commit, but was
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/0eaa3de28270ed6c.
Report an issue: GitHub.
Appendix: source
Thrown at gix-tix/src/edit/undo.rs:599
}
fn encode_state(state: &State) -> BString {
match state {
State::Missing => "missing".into(),
State::Object(id) => format!("object:{id}").into(),
State::Symbolic(name) => {
let mut value = BString::from("symbolic:");
value.extend_from_slice(name.as_bstr());
value
}
}
}
fn parse_config(repo: &gix::Repository, body: &BStr) -> Result<Vec<RefChange>> {
let config = File::try_from(body).context("could not parse undo metadata as Git config")?;
let mut sections = config.sections();
let undo = sections.next().context("undo metadata has no version section")?;
ensure!(
undo.header().name() == b"undo" && undo.header().subsection_name().is_none(),
"undo metadata must start with [undo]"
);
ensure_exact_keys(&undo, &["version"])?;
ensure!(
undo.value("version").as_ref().map(|value| value.as_slice()) == Some(VERSION.as_bytes()),
"unsupported undo metadata version"
);
let mut changes = Vec::new();
let mut previous_name: Option<FullName> = None;
for section in sections {
ensure!(
section.header().name() == b"ref",
"undo metadata contains an unknown section"
);
let subsection = section
.header()View on GitHub (pinned to e73179060b)