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

  1. Renumber existing outgoing edges of the child so the desired order is free before adding
  2. Use an order greater than the current max outgoing edge order
  3. 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

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


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)