GitoxideLabs/gitoxide · error

unsupported undo metadata version

Error message

unsupported undo metadata version

What it means

The `[undo]` section of a queue commit's config carries a `version` key. `parse_config` accepts only the exact `VERSION` string this build understands; any other value means the metadata was written by a different (older or newer) version of the tool whose semantics it cannot safely interpret, so it refuses with this error.

Solutions

  1. Upgrade (or downgrade) gix-tix to the version matching the queue's `version` value and retry undo/redo.
  2. Inspect the queue commit (`git cat-file -p <tip>`) to confirm the recorded version before switching builds.
  3. As a last resort, discard the undo queue (delete/reset the queue refs) and re-record history — losing undo capability for prior edits.

Example fix

// before: queue written by version 2, running binary with VERSION = "1"
[undo]
	version = 2
// after: run the matching tool version, or start a fresh queue
[undo]
	version = 1
Defensive patterns

Strategy: try-catch

Validate before calling

// read the queue's version key and compare against the library VERSION before undo/redo
let body = extract_config_body(&queue_commit);
let file = gix::config::File::try_from(body)?;
let ver = file.raw_value("undo.version");
if ver.map(|v| v != VERSION.as_bytes()).unwrap_or(true) {
    anyhow::bail!("queue version does not match tool version {} — switch builds", VERSION);
}

Try / catch

match repo.undo() {
    Ok(()) => {},
    Err(e) if e.to_string().contains("unsupported undo metadata version") => {
        eprintln!("switch to the gix-tix build matching the queue version");
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: `parse_commit` -> `parse_config` when the queue commit's `[undo] version` key differs from the library's `VERSION` constant — e.g. the queue was written by a newer/older gix-tix build.

Common situations: Downgrading the tool after using a newer queue format; moving a repository between machines with different gix-tix versions; hand-editing the version value.

Related errors


AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08). Data as JSON: /api/errors/a970d93d96c87f1d. Report an issue: GitHub.

Appendix: source

Thrown at gix-tix/src/edit/undo.rs:604

        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()
            .subsection_name()
            .context("an undo ref section has no reference name")?;
        let name = FullName::try_from(subsection).context("an undo entry contains an invalid reference name")?;
        ensure!(!is_queue_ref(name.as_bstr()), "the undo queue records itself");
        if let Some(previous) = &previous_name {

View on GitHub (pinned to e73179060b)