{"record":{"id":"83adf8c014ee7b89","repo":"GitoxideLabs/gitoxide","slug":"present-and-consumed-once","errorCode":null,"errorMessage":"present and consumed once","messagePattern":"present and consumed once","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix/src/clone/checkout.rs","lineNumber":167,"sourceCode":"/// Access\nimpl PrepareCheckout {\n    /// Get access to the repository while the checkout isn't yet completed.\n    ///\n    /// # Panics\n    ///\n    /// If the checkout is completed and the [`Repository`] was already passed on to the caller.\n    pub fn repo(&self) -> &Repository {\n        self.repo\n            .as_ref()\n            .expect(\"present as checkout operation isn't complete\")\n    }\n}\n\n/// Consumption\nimpl PrepareCheckout {\n    /// Persist the contained repository as is even if an error may have occurred when checking out the main working tree.\n    pub fn persist(mut self) -> Repository {\n        self.repo.take().expect(\"present and consumed once\")\n    }\n}\n\nimpl Drop for PrepareCheckout {\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<PrepareCheckout> for Repository {\n    fn from(prep: PrepareCheckout) -> Self {\n        prep.persist()\n    }\n}\n","sourceCodeStart":149,"sourceCodeEnd":184,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix/src/clone/checkout.rs#L149-L184","documentation":"PrepareCheckout::persist() calls self.repo.take().expect(\"present and consumed once\"). It consumes the value via `mut self`, so the Option must still be Some when persist runs. It panics if the repository was already taken - i.e. persist() was called twice, or the repo was already handed over by a successful checkout flow before persist().","triggerScenarios":"Calling persist() twice on the same PrepareCheckout; calling persist() after main_worktree() succeeded and the caller already owns the Repository; calling persist() after the value was previously consumed internally.","commonSituations":"Error-handling paths that persist in multiple branches; storing the value and calling persist in a helper plus a fallback; confusing persist() with a getter.","solutions":["Call persist() exactly once; persist consumes self so the value cannot be used afterwards.","If checkout succeeded, use the Repository returned by main_worktree() instead of calling persist().","Rely on Drop to persist automatically if you cannot decide in code - do not double-persist."],"exampleFix":"// before\nlet repo = prepare.persist();\nlet again = prepare.persist(); // compile error / cannot reuse; pattern of double-consume panics in Drop paths\n// after\nlet repo = prepare.persist(); // exactly once, value consumed","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 checkout already handed you the Repository.","Rely on move semantics: pass PrepareFetch/Checkout 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-15T23:17:13.987Z"}