GitoxideLabs/gitoxide · error
present and consumed once
Error message
present and consumed once
What it means
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.
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).
Example fix
// before let repo = prepare.persist(); let repo2 = prepare.persist(); // cannot happen with move semantics; guard one-shot usage // after let repo = prepare.persist(); // single, final call
Defensive patterns
Strategy: validation
Validate before calling
// persist() consumes self, so the compiler enforces single use; ensure one code path owns it: let repo = prepare.persist();
Prevention
- 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.
When it happens
Trigger: 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).
Common situations: Multiple exit branches each calling persist(); wrapping persist() in a helper called in several places; using persist() after main fetch already returned the Repository.
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
- present and consumed once
- ' ' 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
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/3cf5da9e56a3e143.
Report an issue: GitHub.
Appendix: source
Thrown at gix/src/clone/access.rs:106
&& spec.destination().is_none()
&& (source == "HEAD" || is_full_ref || gix_hash::ObjectId::from_hex(source).is_ok());
is_valid
.then(|| spec.to_owned())
.ok_or(crate::clone::with_revision::Error::Invalid { revision })
})
.transpose()?;
if self.revision.is_some() {
self.ref_name = None;
}
Ok(self)
}
}
/// Consumption
impl PrepareFetch {
/// Persist the contained repository as is even if an error may have occurred when fetching from the remote.
pub fn persist(mut self) -> Repository {
self.repo.take().expect("present and consumed once")
}
}
impl Drop for PrepareFetch {
fn drop(&mut self) {
if let Some(repo) = self.repo.take() {
super::cleanup_clone_destination_on_drop(&repo, self.remove_worktree_on_drop);
}
}
}
impl From<PrepareFetch> for Repository {
fn from(prep: PrepareFetch) -> Self {
prep.persist()
}
}
View on GitHub (pinned to e73179060b)