gitbutlerapp/gitbutler · error
Expected selector to point to a reference
Error message
Expected selector to point to a reference
What it means
LookupStep::lookup_reference resolves a Selector and asserts the step is a Step::Reference, returning the ref's FullName. If the selector resolves to any other step (e.g. a commit Pick), the request is invalid and the library bails.
Solutions
- Inspect editor.lookup_step(selector) to confirm it is Step::Reference first
- Use lookup_pick when the selector targets a commit
- Obtain a fresh selector for the reference from the current editor
Example fix
// before
let refname = editor.lookup_reference(selector)?; // selector is a commit
// after
let refname = match editor.lookup_step(selector)? {
Step::Reference { refname, .. } => refname,
Step::Pick(_) => bail!("expected a reference selector"),
_ => bail!("unsupported step"),
}; Defensive patterns
Strategy: type-guard
Validate before calling
match editor.lookup_step(selector)? { Step::Reference { .. } => {}, _ => bail!("not a reference") } Type guard
fn is_reference_step(editor: &Editor<impl RefMetadata>, s: Selector) -> bool {
matches!(editor.lookup_step(s), Ok(Step::Reference { .. }))
} Try / catch
match editor.lookup_reference(selector) {
Ok(refname) => refname,
Err(_) => bail!("selector does not point at a reference"),
} Prevention
- Call lookup_step first when selector origin is unclear
- Use distinct variables for commit vs reference selectors
When it happens
Trigger: Calling lookup_reference with a selector that resolves to a Pick (commit) or other non-Reference step — e.g. asking for the branch name of a commit selector, or a stale selector after graph mutation.
Common situations: Renaming/moving branches while accidentally passing commit selectors; selectors invalidated by prior move/drop operations shifting node identities.
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 for
- Expected selector to point to a pick
- 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/1679198422a472e6.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-rebase/src/graph_rebase/mod.rs:560
/// Provides lookup for different steps that a selector might point to.
pub trait LookupStep {
/// Look up the step that a given selector corresponds to.
fn lookup_step(&self, selector: Selector) -> Result<Step>;
/// Look up the step a given selector and assert it's a pick.
fn lookup_pick(&self, selector: Selector) -> Result<gix::ObjectId> {
match self.lookup_step(selector)? {
Step::Pick(Pick { id, .. }) => Ok(id),
_ => bail!("Expected selector to point to a pick"),
}
}
/// Look up the step a given selector and assert it's a pick.
fn lookup_reference(&self, selector: Selector) -> Result<gix::refs::FullName> {
match self.lookup_step(selector)? {
Step::Reference { refname, .. } => Ok(refname),
_ => bail!("Expected selector to point to a reference"),
}
}
}
impl<M: RefMetadata> LookupStep for Editor<'_, '_, M> {
fn lookup_step(&self, selector: Selector) -> Result<Step> {
lookup_step(&self.graph, &self.history, selector)
}
}
impl<M: RefMetadata> LookupStep for SuccessfulRebase<'_, '_, M> {
fn lookup_step(&self, selector: Selector) -> Result<Step> {
lookup_step(&self.graph, &self.history, selector)
}
}
impl<M: RefMetadata> LookupStep for MaterializeOutcome<'_, '_, M> {
fn lookup_step(&self, selector: Selector) -> Result<Step> {View on GitHub (pinned to 58e5313667)