GitoxideLabs/gitoxide · error · anyhow::Error
an undo reference state has an unknown encoding
Error message
an undo reference state has an unknown encoding
What it means
Decoder guard in `edit::undo::parse_state`, called from `parse_config` when reading persisted undo-queue state strings. Recognized encodings are `missing`, `object:<hex>` (with a hash-kind check), and `symbolic:<name>`; any other string stored in the undo configuration has an unknown encoding and bails. This fires on corrupted or hand-edited undo queue config data, or state written by a newer/different tool version. Fix by correcting or resetting the undo queue configuration (removing the malformed entries) rather than editing it by hand.
Solutions
- Inspect the raw undo-queue config value and correct it to one of the supported encodings: "missing", "object:<hex-id>", or "symbolic:<full-name>"
- Drop the corrupt undo queue reference and let tix rebuild it from fresh edits
- Upgrade/downgrade tix consistently so queue entries are written and read by the same encoding version
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at gix-tix/src/edit/undo.rs:666 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/88282401223b9243.
Report an issue: GitHub.
Appendix: source
Thrown at gix-tix/src/edit/undo.rs:666
fn parse_state(repo: &gix::Repository, value: &BStr) -> Result<State> {
if value == b"missing" {
return Ok(State::Missing);
}
if let Some(hex) = value.strip_prefix(b"object:") {
let id = ObjectId::from_hex(hex).context("an undo object ID is invalid")?;
ensure!(
id.kind() == repo.object_hash(),
"an undo object ID uses the wrong hash kind"
);
return Ok(State::Object(id));
}
if let Some(name) = value.strip_prefix(b"symbolic:") {
return FullName::try_from(name.as_bstr())
.map(State::Symbolic)
.context("an undo symbolic target is invalid");
}
bail!("an undo reference state has an unknown encoding")
}
fn validate_title(title: &str) -> Result<()> {
ensure!(!title.is_empty(), "an undo operation title cannot be empty");
ensure!(
!title.as_bytes().iter().any(|byte| matches!(byte, b'\n' | b'\r')),
"an undo operation title must be one line"
);
Ok(())
}
fn retention_parents(repo: &gix::Repository, predecessor: ObjectId, changes: &[RefChange]) -> Result<Vec<ObjectId>> {
let mut parents = vec![predecessor];
let mut seen = HashSet::from([predecessor]);
for id in changes
.iter()
.flat_map(|change| [&change.before, &change.after])
.filter_map(|state| match state {View on GitHub (pinned to e73179060b)