gitbutlerapp/gitbutler · error
no commit IDs provided for discard
Error message
no commit IDs provided for discard
What it means
Discarding commits requires at least one commit ID to remove from branch history. The helper `unique_subject_commit_ids` deduplicates the caller-supplied list and bails if nothing remains. This guards downstream rebase machinery from running a pointless or destructive no-op operation.
Solutions
- Ensure the caller collects at least one commit ID before invoking discard
- Check the selection/argument list for emptiness in your UI or CLI layer and short-circuit with a user-facing message
- If IDs may contain duplicates, deduplicate is handled internally, but verify your source of IDs isn't returning an empty set due to a filtering bug
Example fix
// before
api.commit_discard_only(ctx, vec![])?;
// after
if commit_ids.is_empty() {
eprintln!("Nothing selected to discard");
return Ok(());
}
api.commit_discard_only(ctx, commit_ids)?; Defensive patterns
Strategy: validation
Validate before calling
if commit_ids.is_empty() {
return Err(anyhow::anyhow!("nothing selected to discard"));
} Try / catch
match api.commit_discard_only(ctx, ids) {
Err(e) if e.to_string().contains("no commit IDs provided") => warn_user("select commits first"),
other => other?,
} Prevention
- Disable/hide discard actions in the UI until at least one commit is selected
- Validate list arguments at API boundaries before crossing into domain calls
- Remember duplicates are deduped internally — an all-duplicate list still yields entries, only a truly empty set triggers this
When it happens
Trigger: Calling `commit_discard_only_with_perm` or `commit_discard_with_perm` with an empty `subject_commit_ids` vector (or a vector containing only duplicate IDs that dedupe to zero entries).
Common situations: UI layers passing an empty selection when the user confirms discard with nothing selected; CLI argument parsing producing an empty list; upstream filtering logic removing all IDs before the call.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- no commit IDs provided for discard
- Aborting due to empty
- Need at least 2 commits to squash
- No changes were provided to uncommit
- no commit IDs provided for uncommit
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/b6336bf02c0ec5c1.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-api/src/commit/discard_commit.rs:19
use crate::WorkspaceState;
use but_api_macros::but_api;
use but_core::{DiffSpec, DryRun, sync::RepoExclusive};
use but_oplog::legacy::{OperationKind, SnapshotDetails, Trailer};
use but_rebase::graph_rebase::Editor;
use tracing::instrument;
use crate::commit::types::{CommitDiscardResult, MoveChangesResult};
fn unique_subject_commit_ids(
subject_commit_ids: Vec<gix::ObjectId>,
) -> anyhow::Result<Vec<gix::ObjectId>> {
let mut seen = gix::hashtable::HashSet::default();
let subject_commit_ids = subject_commit_ids
.into_iter()
.filter(|commit_id| seen.insert(*commit_id))
.collect::<Vec<_>>();
if subject_commit_ids.is_empty() {
anyhow::bail!("no commit IDs provided for discard");
}
Ok(subject_commit_ids)
}
/// Discard `subject_commit_ids`, removing them from branch history.
///
/// Unlike [`super::uncommit::commit_uncommit()`], the commits' changes are **not**
/// reassigned to the workspace — they are permanently removed from their branches.
///
/// When `dry_run` is enabled, the returned workspace previews the discard
/// without materializing the rebase.
/// See [`commit_discard_only_with_perm()`] for details.
#[but_api(try_from = crate::commit::json::CommitDiscardResult)]
pub fn commit_discard_only(
ctx: &mut but_ctx::Context,
subject_commit_ids: Vec<gix::ObjectId>,
dry_run: DryRun,
) -> anyhow::Result<CommitDiscardResult> {View on GitHub (pinned to 58e5313667)