gitbutlerapp/gitbutler · error
Expected selector for
Error message
Expected selector for {step:?} to refer to a reference What it means
ToReferenceSelector::to_reference_selector normalizes a Selector and asserts the graph node is a Step::Reference (a named ref such as a branch). If it resolves to any other step kind (e.g. a Pick/commit), the conversion is invalid and the library bails.
Solutions
- Verify editor.graph[selector.id] is a Step::Reference before the call
- Use to_commit_selector if the selector targets a commit
- Re-derive the selector from the current editor/graph state
Example fix
// before: selector points at a commit -> error
let refname = selector.to_reference_selector(&editor)?;
// after
let step = &editor.graph[selector.id];
let refname = match step {
Step::Reference { .. } => selector.to_reference_selector(&editor)?,
Step::Pick(_) => bail!("use a reference selector here"),
_ => bail!("unsupported step"),
}; Defensive patterns
Strategy: type-guard
Validate before calling
let step = &editor.graph[selector.id];
if !matches!(step, Step::Reference { .. }) { return Err(anyhow!("not a reference selector")); } Type guard
fn is_reference(selector: Selector, editor: &Editor<impl RefMetadata>) -> bool {
matches!(editor.graph[selector.id], Step::Reference { .. })
} Try / catch
match selector.to_reference_selector(&editor) {
Ok(r) => r,
Err(_) => bail!("selector does not refer to a reference; check step kind first"),
} Prevention
- Keep commit and reference selectors in separate typed variables
- Re-derive selectors from the editor after mutations
When it happens
Trigger: Calling to_reference_selector with a Selector that normalizes to a non-Reference step — e.g. passing a commit-pick selector into a move-branch/rename-reference API, or a stale selector that re-resolves to a Pick after graph edits.
Common situations: Confusing commit selectors with branch selectors when scripting rebase graph mutations; calling branch operations on commit ids; selectors invalidated by earlier mutations to the editor graph.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Expected selector for
- Expected selector to point to a pick
- Expected selector to point to a reference
- Expected target tip selector to point to a pick
- Reference target in rebase result is not a commit
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/5cc103df3d7c8733.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-rebase/src/graph_rebase/mod.rs:233
impl ToCommitSelector for Selector {
fn to_commit_selector(&self, editor: &Editor<impl RefMetadata>) -> Result<Selector> {
let selector = editor.history.normalize_selector(*self)?;
let step = &editor.graph[selector.id];
if !matches!(step, Step::Pick(_)) {
bail!("Expected selector for {step:?} to refer to a commit");
}
Ok(selector)
}
}
impl ToReferenceSelector for Selector {
fn to_reference_selector(&self, editor: &Editor<impl RefMetadata>) -> Result<Selector> {
let selector = editor.history.normalize_selector(*self)?;
let step = &editor.graph[selector.id];
if !matches!(step, Step::Reference { .. }) {
bail!("Expected selector for {step:?} to refer to a reference");
}
Ok(selector)
}
}
impl ToSelector for Selector {
fn to_selector(&self, _: &Editor<impl RefMetadata>) -> Result<Selector> {
Ok(*self)
}
}
/// Represents places where `safe_checkout` should be called from
#[derive(Debug, Clone)]
pub(crate) enum Checkout {
/// The HEAD of the `repo` the editor was created for.
Head {
selector: Selector,View on GitHub (pinned to 58e5313667)