gitbutlerapp/gitbutler · error
An edge with desired order
Error message
An edge with desired order {desired_order} already exists What it means
add_edge inserts a child->parent edge with an explicit sibling order among a child's parents. The graph already has an outgoing edge from the child with the requested order, so adding another would create an ambiguous ordering; the library refuses rather than producing a corrupted parent sequence.
Solutions
- Renumber existing outgoing edges of the child so the desired order is free before adding
- Use an order greater than the current max outgoing edge order
- Check existing edges with graph.edges_directed(child.id, Outgoing) to pick a free order
Example fix
// before editor.add_edge(child, new_parent, 0)?; // order 0 already taken // after let next = editor.graph.edges_directed(child.id, Direction::Outgoing).count() as u64; editor.add_edge(child, new_parent, next)?;
Defensive patterns
Strategy: validation
Validate before calling
let taken: HashSet<u64> = editor.graph.edges_directed(child.id, Direction::Outgoing)
.map(|e| e.weight().order).collect();
if taken.contains(&desired_order) { return Err(anyhow!("order {} taken", desired_order)); } Type guard
fn order_free(editor: &Editor<impl RefMetadata>, child: Selector, order: u64) -> bool {
!editor.graph.edges_directed(child.id, Direction::Outgoing)
.any(|e| e.weight().order == order)
} Prevention
- Renumber sibling edges after insertions/removals
- Track the next free order per child node
- Never assume a fixed default order when adding multiple parents
When it happens
Trigger: Calling add_edge (public) with a desired_order that collides with an existing outgoing edge of child.id — e.g. adding two parents both at order 0, or re-adding an edge without first shifting orders of existing edges.
Common situations: Building merge-commit parent lists where orders weren't renumbered after an insertion/removal; retrying a failed graph mutation that partially applied; programmatic squashes that reattach parents with default order 0.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- A matching parent can't be found in the output graph
- A parent in the output graph is not a pick
- Cannot order selected commits by parentage: selected commit
- Commit was marked as not conflictable, but resulted in a…
- Failed to find corresponding parent
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/1165de7cac1e3b79.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-rebase/src/graph_rebase/mutate.rs:843
pub fn add_edge(
&mut self,
child: impl ToSelector,
parent: impl ToSelector,
desired_order: usize,
) -> Result<()> {
let child = self.history.normalize_selector(child.to_selector(self)?)?;
let parent = self.history.normalize_selector(parent.to_selector(self)?)?;
if has_path_connecting(&self.graph, parent.id, child.id, None) {
bail!("BUG: Add edge introduces a cycle");
}
if self
.graph
.edges_directed(child.id, Direction::Outgoing)
.any(|edge| edge.weight().order == desired_order)
{
bail!("An edge with desired order {desired_order} already exists");
}
self.graph.add_edge(
child.id,
parent.id,
Edge {
order: desired_order,
},
);
Ok(())
}
/// Removes all edges between a child and parent, returning the orders of the removed edges.
pub fn remove_edges(
&mut self,
child: impl ToSelector,
parent: impl ToSelector,View on GitHub (pinned to 58e5313667)