{"record":{"id":"0643292b6a928dfc","repo":"GitoxideLabs/gitoxide","slug":"bug-must-not-add-entries-after-the-start-of-entri","errorCode":null,"errorMessage":"BUG: must not add entries after the start of entries traversal","messagePattern":"BUG: must not add entries after the start of entries traversal","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-worktree-stream/src/lib.rs","lineNumber":118,"sourceCode":"            err: Default::default(),\n            buf: std::iter::repeat_n(0, u16::MAX as usize).collect(),\n            pos: 0,\n            filled: 0,\n        }\n    }\n}\n\n/// Entries\nimpl Stream {\n    /// Add `entry` to the list of entries to be returned in calls to [`Self::next_entry()`].\n    ///\n    /// The entry will be returned after the one contained in the tree, in order of addition.\n    /// # Panics\n    /// If called after the first call to [`Self::next_entry()`].\n    pub fn add_entry(&mut self, entry: AdditionalEntry) -> &mut Self {\n        self.extra_entries\n            .as_ref()\n            .expect(\"BUG: must not add entries after the start of entries traversal\")\n            .send(entry)\n            .expect(\"Failure is impossible as thread blocks on the receiving end\");\n        self\n    }\n\n    /// Add the item at `path` as entry to this stream, which is expected to be under `root`.\n    ///\n    /// Note that the created entries will always have a null hash, and that we access this path\n    /// to determine its type, and will access it again when it is requested.\n    pub fn add_entry_from_path(\n        &mut self,\n        root: &Path,\n        path: &Path,\n        object_hash: gix_hash::Kind,\n    ) -> std::io::Result<&mut Self> {\n        let rela_path = path.strip_prefix(root).map_err(std::io::Error::other)?;\n        let meta = path.symlink_metadata()?;\n        let relative_path = gix_path::to_unix_separators_on_windows(gix_path::into_bstr(rela_path)).into_owned();","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-worktree-stream/src/lib.rs#L100-L136","documentation":"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.","triggerScenarios":"Calling stream.add_entry(...) (directly or via add_entry_from_path) after the first stream.next_entry() call has been made.","commonSituations":"Building the entry list lazily as you read; adding a late-discovered file after traversal started; confusing ordering of setup code versus iteration code.","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."],"exampleFix":"// before\nlet e = stream.next_entry()?;\nstream.add_entry(extra)?; // panics: traversal started\n// after\nstream.add_entry(extra)?;\nlet e = stream.next_entry()?;","handlingStrategy":"validation","validationCode":"if stream.has_started_traversal() { /* API-specific guard if available */ }\n// In practice: add all entries before the first next_entry() call.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["rust","panic","invalid-state-transition","stream"],"backgroundTag":"invalid-state-transition","analyzedSha":"e73179060badf27222d790981fac3f84c1830a7e","analyzedAt":"2026-09-08T11:26:50.865Z","contentChangedAt":"2026-09-08T11:26:50.865Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}