gitbutlerapp/gitbutler · error
Expected reference selector to point to a commit
Error message
Expected reference selector to point to a commit
What it means
Raised by `first_pick_parent` in crates/but-workspace/src/divergence.rs:185 while walking adjacent reference selectors to find one whose lookup step is a `Pick`. If no adjacent candidate resolves to a pick step, the function concludes the selector does not point to a commit and errors. Exposed via `tip_for_ref`.
Solutions
- Verify the reference resolves to a commit (`peel to commit`) before computing divergence
- Rebuild/refresh workspace metadata so the editor's step log matches the repository state
- Check the branch was created by a supported operation (not hand-edited refs)
- Report as a bug if a normal branch triggers it — this usually indicates an invariant violation
Example fix
// before let tip = tip_for_ref(&editor, ref_name, &repo)?; // after let commit = repo.find_reference(ref_name)?.peel_to_commit()?; let tip = tip_for_ref(&editor, ref_name, &repo)?;
Defensive patterns
Strategy: validation
Validate before calling
let commit = repo.find_reference(ref_name)?.peel_to_commit()
.context("ref does not point to a commit; divergence cannot be computed")?; Try / catch
match tip_for_ref(&editor, ref_name, &repo) {
Err(e) if e.to_string().contains("Expected reference selector") => refresh_workspace_state_and_retry(),
other => other?,
} Prevention
- Only compute divergence for refs that peel to commits
- Avoid hand-editing refs; use supported branch operations
- Rebuild workspace metadata if operations were interrupted
When it happens
Trigger: Computing divergence for a reference whose selector history contains no `Pick` steps — e.g. the ref points at a non-commit object or the editor's step log lacks pick entries for adjacent candidates.
Common situations: Refs pointing at tags or blobs instead of commits; workspace metadata out of sync with the underlying repository; internal state corruption after interrupted operations.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- BUG: failed to apply head ref
- Aborting due to empty branch name
- Ad-hoc (single-branch) branch moves are not supported…
- An octopus merge commits must have at least two parents
- another pre-commit hook is already using the repository…
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/52aeb1c6809a9c9c.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-workspace/src/divergence.rs:185
};
Ok((candidate_commit_id, relation))
})
.collect()
}
fn first_pick_parent<M: RefMetadata>(
editor: &Editor<'_, '_, M>,
selector: Selector,
) -> Result<Selector> {
let mut adjacent = editor.direct_parents(selector)?;
adjacent.extend(editor.direct_children(selector)?);
adjacent.sort_by_key(|(_, order)| *order);
adjacent
.into_iter()
.find_map(|(candidate, _)| {
matches!(editor.lookup_step(candidate).ok()?, Step::Pick(_)).then_some(candidate)
})
.ok_or_else(|| anyhow::anyhow!("Expected reference selector to point to a commit"))
}
fn tip_for_ref<M: RefMetadata>(
editor: &Editor<'_, '_, M>,
ref_name: &gix::refs::FullNameRef,
repo: &gix::Repository,
) -> Result<Selector> {
let reference_selector = ref_name.to_selector(editor)?;
let head_id = repo.head_id()?.detach();
if let Some(child_on_head_path) =
child_on_head_first_parent_path(editor, reference_selector, head_id)?
{
return Ok(child_on_head_path);
}
first_pick_parent(editor, reference_selector).or_else(|_| {
let tip = repo.find_reference(ref_name)?.id().detach();
editor.select_commit(tip)
})View on GitHub (pinned to 58e5313667)