GitoxideLabs/gitoxide · error · anyhow::Error
could not persist a prepared rebase object
Error message
could not persist a prepared rebase object: {err} What it means
During a tix rebase, prepared objects are staged in memory and then flushed with `repo.write_buf_with_known_id`. If any write fails, the error is wrapped as "could not persist a prepared rebase object: {err}" and the rebase cannot continue. `write_buf_with_known_id` also validates the caller-supplied id, so a hash mismatch surfaces here.
Solutions
- Free disk space / fix .git/objects permissions and retry the rebase
- Check the inner error for which object failed; verify it isn't an id mismatch
- Abort and restart the rebase; in-memory objects are rebuilt deterministically
Defensive patterns
Strategy: try-catch
Validate before calling
fn odb_writable(repo: &gix::Repository) -> bool {
repo.workdir()
.map(|d| d.join("objects").metadata().map(|m| !m.permissions().readonly()).unwrap_or(false))
.unwrap_or(false)
} Try / catch
if let Err(e) = rebase.persist_objects() {
anyhow::bail!("rebase aborted, prepared objects not persisted: {e:#}");
} Prevention
- Ensure adequate free space before large rebases
- Verify hash algorithm consistency (sha1 vs sha256) across tooling versions
- Abort and restart rebases cleanly instead of resuming after IO failures
When it happens
Trigger: Rebase edit operations in gix-tix (`edit/rebase.rs` persist path) where the object database write fails — unwritable .git/objects, disk full, or object id/kind mismatch between computed and stored data.
Common situations: Disk-quota or permission problems mid-rebase; very large rebases exhausting space; mismatches after hash-algorithm or library version changes.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- could not inspect a reference before rebasing
- {err}
- One or more errors occurred - checkout is incomplete
- At least one object couldn't be looked up even though it…
- rebase todo requires at least one -x/--hide revision when…
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/9bbf59112d178bc7.
Report an issue: GitHub.
Appendix: source
Thrown at gix-tix/src/edit/rebase.rs:2158
let selected = prepared.selected.context("an enriched edit must select its commit")?;
let Some((object, data, enrichment)) = crate::enrich::prepare_headers(&prepared.repo, selected, headers)? else {
return Ok(None);
};
prepared.enrichment = Some((object, data));
Ok(Some(enrichment))
}
impl Prepared {
fn persist_objects(&mut self) -> Result<()> {
let objects = self
.repo
.objects
.take_object_memory()
.context("candidate object memory was unavailable")?;
for (id, (kind, data)) in objects.iter() {
self.repo
.write_buf_with_known_id(*kind, data, *id)
.map_err(|err| anyhow::anyhow!("could not persist a prepared rebase object: {err}"))?;
}
self.repo.objects.set_object_memory(Default::default());
Ok(())
}
fn finish(&mut self) -> Result<Outcome> {
let mut resource_edits = super::stash::rewrite_edits(&self.repo, &self.stash_rewritten, &self.removed)?;
let note_edits = note_rewrite_edits(&self.repo, &self.note_rewrites, &self.committer)?;
let enrichment_edits = self
.enrichment
.take()
.map(|(object, data)| enrichment_edits(&self.repo, object, data, &self.committer))
.transpose()?
.unwrap_or_else(|| super::stash::RewriteEdits {
forward: Vec::new(),
rollback: Vec::new(),
});
resource_edits.forward.extend(note_edits.forward);View on GitHub (pinned to e73179060b)