GitoxideLabs/gitoxide · error
BUG: Invalid state: we never discard only our file, always…
Error message
BUG: Invalid state: we never discard only our file, always both.
What it means
An `unreachable!()` panic in gix-ref's packed+loose reflog iterator `next()` (`store/file/log/iter`). The iterator walks two sources (own-file and packed reflog) in lockstep and asserts it never reaches the state `(Some(_), None)` — having only the own-file entry while the packed side is exhausted — because both files are discarded together during iteration. The panic fires if that invariant breaks.
Solutions
- Restore reflog consistency: run `git reflog` / `git fsck` with real git, or delete the affected reflog files (`rm -rf .git/logs/<ref>`) so they can be rebuilt
- Re-clone or re-pack the repository if reflog history is disposable (`git clone --mirror` + fresh fetch)
- Upgrade gix / gix-ref and retry; report the repository layout that triggered it upstream
Defensive patterns
Strategy: validation
Validate before calling
use std::path::Path;
fn reflog_files_consistent(git_dir: &Path, ref_name: &str) -> bool {
let loose = git_dir.join("logs").join(ref_name);
loose.exists() // if loose reflog exists, packed side is derived automatically; manual deletion of one side is the risk
} Try / catch
std::panic::catch_unwind(|| iter.collect::<Vec<_>>())
.map_err(|_| "reflog iteration hit inconsistent storage; rebuild reflogs")? Prevention
- Do not manually delete individual reflog files under .git/logs; remove whole reflogs instead
- Run `git fsck` after tooling that rewrites ref storage (gc, repack, migrations)
- Avoid interleaving gix and git ref-rewriting operations on the same repo mid-flight
- Keep gix-ref updated; iterator state-machine bugs are fixed in releases
When it happens
Trigger: Iterating a reflog (e.g. `repo.reflog()` or reflog-based history traversal) over a repository where the loose reflog file and the packed-refs reflog are out of sync in a way the iterator didn't anticipate — e.g. manually deleted or partially compacted files under `.git/logs/`, or a gix-ref iteration bug.
Common situations: Repositories maintained by mixed tooling (git gc/repack interleaved with gix, manual cleanup of `.git/logs`), corrupted or hand-edited reflog storage, or fresh gix versions with iterator regressions.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- we are called from a valid ref
- this one only happens on iteration creation
- BUG: tries to obtain object id from symbolic target
- BUG: expected peeled reference target but found symbolic one
- no item index implies having an object id
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/a7fafb76c93f7bed.
Report an issue: GitHub.
Appendix: source
Thrown at gix-ref/src/store/file/log/iter.rs:240
.into()));
}
let n = (last_read_pos - npos) as usize;
self.buf.copy_within(0..end, n);
if let Err(err) = read.seek(std::io::SeekFrom::Start(npos)) {
return Some(Err(err.into()));
}
if let Err(err) = read.read_exact(&mut self.buf[..n]) {
return Some(Err(err.into()));
}
self.read_and_pos = Some((read, npos));
self.last_nl_pos = Some(n + end);
self.next()
}
}
},
// depleted
(None, None) => None,
(Some(_), None) => unreachable!("BUG: Invalid state: we never discard only our file, always both."),
}
}
}
View on GitHub (pinned to e73179060b)