gitbutlerapp/gitbutler · error
Invalid parents to disconnect: SelectorSet::None is not allo
Error message
Invalid parents to disconnect: SelectorSet::None is not allowed
What it means
`Editor::disconnect_segment_from` documents (and enforces) that `parents_to_disconnect = SelectorSet::None` is only legal when `skip_reconnect_step` is true. With None-parents and reconnection enabled, every disconnected child would need to be reconnected to an empty parent set — an ill-defined operation — so the editor rejects the combination up front.
Source
Thrown at crates/but-rebase/src/graph_rebase/mutate.rs:409
SelectorSet::Some(children) => Some(
children
.as_slice()
.iter()
.map(|from_child| from_child.to_selector(self))
.collect::<Result<Vec<_>>>()?
.into_iter()
.map(|selector| self.history.normalize_selector(selector))
.collect::<Result<Vec<_>>>()?,
),
};
let parents_to_disconnect = match parents_to_disconnect {
SelectorSet::All => None,
SelectorSet::None => {
if skip_reconnect_step {
Some(Vec::new())
} else {
return Err(anyhow!(
"Invalid parents to disconnect: SelectorSet::None is not allowed"
));
}
}
SelectorSet::Some(parents) => Some(
parents
.as_slice()
.iter()
.map(|from_parent| from_parent.to_selector(self))
.collect::<Result<Vec<_>>>()?
.into_iter()
.map(|selector| self.history.normalize_selector(selector))
.collect::<Result<Vec<_>>>()?,
),
};
// Edges to children.
let incoming_edges = selfView on GitHub (pinned to caf1f223d3)
Solutions
- If you really want to disconnect with no parents and no reconnection, pass `skip_reconnect_step = true`
- If children should be reattached, specify the parents explicitly with `SelectorSet::Some(SomeSelectors::new([...])?)`
- To disconnect from everything, use `SelectorSet::All`
- Re-read the doc comment on `disconnect_segment_from` — the error conditions are enumerated there verbatim
Example fix
// before editor.disconnect_segment_from(target, children, SelectorSet::None, /* skip_reconnect_step */ false)?; // Err // after — pick the intended contract: editor.disconnect_segment_from(target, children, SelectorSet::None, true)?; // no reconnect // or editor.disconnect_segment_from(target, children, SelectorSet::Some(SomeSelectors::new(parents)?), false)?; // reconnect to explicit parents
Defensive patterns
Strategy: validation
Validate before calling
// Mirror the documented contract before calling:
if matches!(parents_to_disconnect, SelectorSet::None) {
anyhow::ensure!(skip_reconnect_step,
"SelectorSet::None parents requires skip_reconnect_step = true");
}
editor.disconnect_segment_from(target, children, parents_to_disconnect, skip_reconnect_step)?; Prevention
- Encode the contract once in a wrapper that maps (parents, skip_reconnect) combinations
- Write unit tests covering None/All/Some parent combinations so invalid ones never reach the editor
- Read the doc comment on disconnect_segment_from; the error conditions are listed verbatim
When it happens
Trigger: Calling `disconnect_segment_from(target, children, SelectorSet::None, false)` — i.e. disconnecting children while specifying no parents to reconnect them to, without opting out of the reconnect step.
Common situations: Callers translating a UI action like 'detach these children only' into editor calls without realizing the default contract; porting code from an older signature where None had different semantics.
Related errors
- Invalid parent delimitation: requested parent is not a direc
- Invalid parent delimitation: requested child is not a direct
- Invalid message format
- HTTP Error ${response.statusText}: ${text}
- Invalid section for global key: {key}
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/46e8652088015a06.
Report an issue: GitHub.