gitbutlerapp/gitbutler · error
No commits were provided to squash
Error message
No commits were provided to squash
What it means
commit_squash_only_with_perm (the squash entry point behind the but-api squash surface) validates up front that subject_commit_ids is non-empty; an empty selection means there is nothing to fold into the target commit, so it bails before opening the workspace or creating an Editor.
Source
Thrown at crates/but-api/src/commit/squash.rs:54
guard.write_permission(),
)
}
/// Squash `subject_commit_ids` into `target_commit_id` under caller-held
/// exclusive repository access.
///
/// This variant does not create an oplog entry. When `dry_run` is enabled, it
/// returns a preview of the resulting workspace state without materializing the rebases.
pub fn commit_squash_only_with_perm(
ctx: &mut but_ctx::Context,
subject_commit_ids: Vec<gix::ObjectId>,
target_commit_id: gix::ObjectId,
how_to_combine_messages: MessageCombinationStrategy,
dry_run: DryRun,
perm: &mut RepoExclusive,
) -> anyhow::Result<CommitSquashResult> {
if subject_commit_ids.is_empty() {
anyhow::bail!("No commits were provided to squash")
}
let mut meta = ctx.meta()?;
let (repo, mut ws, mut db) = ctx.workspace_mut_and_db_mut_with_perm(perm)?;
let editor = Editor::create(&mut ws, &mut meta, &repo, &mut db)?;
let SquashCommitsOutcome {
rebase,
commit_selector,
} = but_workspace::commit::squash_commits(
editor,
subject_commit_ids,
target_commit_id,
how_to_combine_messages,
)?;
let new_commit = rebase.lookup_pick(commit_selector)?;
let workspace = WorkspaceState::from_successful_rebase(rebase, &repo, dry_run)?;
Ok(CommitSquashResult {
new_commit,View on GitHub (pinned to 2497b8007a)
Solutions
- Pass at least one commit id to squash into the target commit.
- Guard the caller: treat an empty selection as a no-op or disable the action instead of invoking the API.
- In UIs, require a non-empty selection before enabling squash.
Example fix
// before
but_api::commit_squash_only_with_perm(ctx, vec![], target_id, how, DryRun::No, perm)?;
// after
if !subject_commit_ids.is_empty() {
but_api::commit_squash_only_with_perm(ctx, subject_commit_ids, target_id, how, DryRun::No, perm)?;
} Defensive patterns
Strategy: validation
Validate before calling
fn can_squash(subject_commit_ids: &[gix::ObjectId]) -> bool {
!subject_commit_ids.is_empty()
} Prevention
- Validate a non-empty selection at the UI/CLI boundary.
- Treat an empty selection as a no-op in callers rather than an API error.
- Compute commit lists before invoking and bail early when filters match nothing.
When it happens
Trigger: Calling commit_squash_only_with_perm or its but-api wrapper with an empty Vec<gix::ObjectId> — typically a UI passing an empty multi-selection or a script computing a commit list from a filter that matched nothing.
Common situations: Frontends not disabling the squash action with nothing selected; batch pipelines looping over zero matched commits; selection state lost before the call.
Related errors
- no commit IDs provided for uncommit
- HTTP Error ${response.statusText}: ${text}
- Branch {branch_name} not found
- Failed to create pull request: {status} - {error_text}
- source branches is already checked to be non-empty
AI-assisted analysis of gitbutlerapp/gitbutler@2497b8007a (2026-08-17).
Data as JSON: /api/errors/5627b88d117791bf.
Report an issue: GitHub.