gitbutlerapp/gitbutler · error
Cannot cherry-pick above a reference
Error message
Cannot cherry-pick above a reference
What it means
cherry_pick_commits rejects the combination RelativeTo::Reference(_) with InsertSide::Above: inserting commits above a reference would require rewriting what the ref points at in a way the rebase editor model does not support for this operation. Inserting below a reference, or above/below a commit, is fine. The check runs before any selector resolution.
Source
Thrown at crates/but-workspace/src/commit/cherry_pick.rs:40
pub fn cherry_pick_commits<'ws, 'meta, M: RefMetadata>(
mut editor: Editor<'ws, 'meta, M>,
source_commits: impl IntoIterator<Item = gix::ObjectId>,
relative_to: RelativeTo,
side: InsertSide,
) -> anyhow::Result<(SuccessfulRebase<'ws, 'meta, M>, Vec<Selector>)> {
let mut seen = HashSet::new();
let sources = source_commits
.into_iter()
.filter(|id| seen.insert(*id))
.collect::<Vec<_>>();
if sources.is_empty() {
bail!("No commits were provided to cherry-pick")
}
if matches!(
(&relative_to, side),
(RelativeTo::Reference(_), InsertSide::Above)
) {
bail!("Cannot cherry-pick above a reference")
}
let target = relative_to.to_selector(&editor)?;
let mut inserted_selectors = Vec::with_capacity(sources.len());
let mut previous_selector = None;
for source in sources {
// Give the copy its own change ID, retaining all other metadata.
let mut template = editor.find_commit(source)?;
let mut headers = Headers::try_from_commit(&template.inner).unwrap_or_default();
headers.change_id = Headers::from_config(&editor.repo().config_snapshot()).change_id;
headers.set_in_commit(&mut template.inner);
let template_id = editor.new_commit(template, DateMode::CommitterUpdateAuthorKeep)?;
let (anchor, insert_side) = match previous_selector {
Some(selector) => (selector, InsertSide::Above),
None => (target, side),
};View on GitHub (pinned to caf1f223d3)
Solutions
- Use InsertSide::Below when the anchor is a reference, or anchor Above on a commit instead.
- Disable the 'above' placement option in the UI when the drop target is a branch/reference.
- Validate the (relative_to, side) pair before invoking the API.
Example fix
// before cherry_pick_commits(editor, ids, RelativeTo::Reference(target_ref), InsertSide::Above)?; // after cherry_pick_commits(editor, ids, RelativeTo::Reference(target_ref), InsertSide::Below)?;
Defensive patterns
Strategy: validation
Validate before calling
if matches!((&relative_to, side), (RelativeTo::Reference(_), InsertSide::Above)) {
// invalid combination: clamp to Below or reject before calling
return Err(anyhow!("cannot insert above a reference"));
} Type guard
fn cherry_pick_args_valid(relative_to: &RelativeTo, side: InsertSide) -> bool {
!matches!((relative_to, side), (RelativeTo::Reference(_), InsertSide::Above))
} Prevention
- Only offer 'above' placement when the anchor is a commit.
- Validate the (anchor kind, side) pair at the UI/action layer.
- Document that references accept Below only.
When it happens
Trigger: Calling cherry_pick_commits(editor, ids, RelativeTo::Reference(r), InsertSide::Above) — any reference anchor with the Above side.
Common situations: UIs exposing 'insert above' generically for both commit and branch targets; parameter mapping bugs that reuse InsertSide::Above for a reference target.
Related errors
- No commits were provided to cherry-pick
- Failed to communicate with LM Studio server: ${error instanc
- Invalid response: ${JSON.stringify(result)}
- When using GitButler's API to summarize code, you must be lo
- When using LM Studio, you must provide a valid endpoint
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/45a10bf32453f17f.
Report an issue: GitHub.