{"record":{"id":"3cf5da9e56a3e143","repo":"GitoxideLabs/gitoxide","slug":"present-and-consumed-once-3cf5da","errorCode":null,"errorMessage":"present and consumed once","messagePattern":"present and consumed once","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix/src/clone/access.rs","lineNumber":106,"sourceCode":"                    && spec.destination().is_none()\n                    && (source == \"HEAD\" || is_full_ref || gix_hash::ObjectId::from_hex(source).is_ok());\n                is_valid\n                    .then(|| spec.to_owned())\n                    .ok_or(crate::clone::with_revision::Error::Invalid { revision })\n            })\n            .transpose()?;\n        if self.revision.is_some() {\n            self.ref_name = None;\n        }\n        Ok(self)\n    }\n}\n\n/// Consumption\nimpl PrepareFetch {\n    /// Persist the contained repository as is even if an error may have occurred when fetching from the remote.\n    pub fn persist(mut self) -> Repository {\n        self.repo.take().expect(\"present and consumed once\")\n    }\n}\n\nimpl Drop for PrepareFetch {\n    fn drop(&mut self) {\n        if let Some(repo) = self.repo.take() {\n            super::cleanup_clone_destination_on_drop(&repo, self.remove_worktree_on_drop);\n        }\n    }\n}\n\nimpl From<PrepareFetch> for Repository {\n    fn from(prep: PrepareFetch) -> Self {\n        prep.persist()\n    }\n}\n","sourceCodeStart":88,"sourceCodeEnd":123,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix/src/clone/access.rs#L88-L123","documentation":"PrepareFetch::persist() calls self.repo.take().expect(\"present and consumed once\"). Like PrepareCheckout::persist, it moves the Repository out exactly once; the expect fires if the Option is already None because persist() was called before or the repository was already handed over by the fetch flow.","triggerScenarios":"Calling persist() twice on the same PrepareFetch; calling persist() after a previous code path consumed the internal repo (e.g. success path already moved it).","commonSituations":"Multiple exit branches each calling persist(); wrapping persist() in a helper called in several places; using persist() after main fetch already returned the Repository.","solutions":["Call persist() exactly once on the owned PrepareFetch value.","If fetch succeeded, use the Repository returned by the fetch call instead of persist().","Ensure only one code path can reach persist() (consume self; persist is a one-shot method)."],"exampleFix":"// before\nlet repo = prepare.persist();\nlet repo2 = prepare.persist(); // cannot happen with move semantics; guard one-shot usage\n// after\nlet repo = prepare.persist(); // single, final call","handlingStrategy":"validation","validationCode":"// persist() consumes self, so the compiler enforces single use; ensure one code path owns it:\nlet repo = prepare.persist();","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Call persist() exactly once, as the final operation on the value.","Do not call persist() after fetch already handed you the Repository.","Rely on move semantics: pass PrepareFetch into a single finishing function."],"tags":["rust","panic","consumption","ownership"],"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-16T04:17:20.429Z"}