GitoxideLabs/gitoxide · error
BUG: must not add entries after the start of entries…
Error message
BUG: must not add entries after the start of entries traversal
What it means
Stream::add_entry() panics when extra_entries channel is None, which happens after the first call to next_entry() started entry traversal. Additional entries are delivered via a channel that is only present before traversal begins, so adding entries mid-traversal is an invalid state the library asserts against.
Solutions
- Call add_entry() for all additional entries BEFORE the first next_entry() call.
- Re-create the Stream if you need to add entries after traversal already started.
- Restructure so the set of extra entries is known up front.
Example fix
// before let e = stream.next_entry()?; stream.add_entry(extra)?; // panics: traversal started // after stream.add_entry(extra)?; let e = stream.next_entry()?;
Defensive patterns
Strategy: validation
Validate before calling
if stream.has_started_traversal() { /* API-specific guard if available */ }
// In practice: add all entries before the first next_entry() call. Prevention
- Set up all additional entries immediately after constructing the Stream.
- Never interleave add_entry() with next_entry() calls.
- Treat Stream setup and traversal as two strictly separated phases.
When it happens
Trigger: Calling stream.add_entry(...) (directly or via add_entry_from_path) after the first stream.next_entry() call has been made.
Common situations: Building the entry list lazily as you read; adding a late-discovered file after traversal started; confusing ordering of setup code versus iteration code.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- ' ' is not a valid configuration key
- Cannot use iter_v1() on index of type
- Cannot use iter_v2() on index of type
- BUG: tries to obtain object id from symbolic target
- BUG: expected peeled reference target but found symbolic one
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/0643292b6a928dfc.
Report an issue: GitHub.
Appendix: source
Thrown at gix-worktree-stream/src/lib.rs:118
err: Default::default(),
buf: std::iter::repeat_n(0, u16::MAX as usize).collect(),
pos: 0,
filled: 0,
}
}
}
/// Entries
impl Stream {
/// Add `entry` to the list of entries to be returned in calls to [`Self::next_entry()`].
///
/// The entry will be returned after the one contained in the tree, in order of addition.
/// # Panics
/// If called after the first call to [`Self::next_entry()`].
pub fn add_entry(&mut self, entry: AdditionalEntry) -> &mut Self {
self.extra_entries
.as_ref()
.expect("BUG: must not add entries after the start of entries traversal")
.send(entry)
.expect("Failure is impossible as thread blocks on the receiving end");
self
}
/// Add the item at `path` as entry to this stream, which is expected to be under `root`.
///
/// Note that the created entries will always have a null hash, and that we access this path
/// to determine its type, and will access it again when it is requested.
pub fn add_entry_from_path(
&mut self,
root: &Path,
path: &Path,
object_hash: gix_hash::Kind,
) -> std::io::Result<&mut Self> {
let rela_path = path.strip_prefix(root).map_err(std::io::Error::other)?;
let meta = path.symlink_metadata()?;
let relative_path = gix_path::to_unix_separators_on_windows(gix_path::into_bstr(rela_path)).into_owned();View on GitHub (pinned to e73179060b)