gitbutlerapp/gitbutler · warning
No uncommitted changes assigned to branch: {branch_name}
Error message
No uncommitted changes assigned to branch: {branch_name} What it means
The absorb plan found the stack owning the requested branch, but none of the current hunk assignments carry that stack's ID — no uncommitted changes are assigned to the branch — so there is nothing to absorb and the plan bails. It is effectively a nothing-to-do condition reported as an error.
Source
Thrown at crates/but-api/src/legacy/absorb.rs:164
.iter()
.find(|s| {
s.heads
.iter()
.any(|h| h.name.to_str().map(|n| n == branch_name).unwrap_or(false))
})
.ok_or_else(|| anyhow::anyhow!("Branch not found: {branch_name}"))?;
let stack_id = stack.id.ok_or_else(|| anyhow::anyhow!("Stack has no ID"))?;
// Filter assignments to just this stack
let candidates: Vec<AbsorbCandidate> = all_assignments
.into_iter()
.filter(|a| a.stack_id == Some(stack_id))
.map(Into::into)
.collect();
if candidates.is_empty() {
anyhow::bail!("No uncommitted changes assigned to branch: {branch_name}");
}
(candidates, dependencies)
}
AbsorptionTarget::TreeChanges {
changes,
assigned_stack_id,
} => {
// Get all worktree changes, assignments, and dependencies
let worktree_changes = crate::diff::changes_in_worktree_with_perm(
ctx,
ChangesSource::Head,
true,
perm.read_permission(),
)?;
let all_assignments = worktree_changes.assignments;
let dependencies = worktree_changes.dependencies;
View on GitHub (pinned to 2497b8007a)
Solutions
- Assign the pending changes to the branch (hunk assignment UI or equivalent) and retry.
- Or use the TreeChanges absorption target to absorb explicitly selected files.
- Confirm with `but status` that the branch actually has assigned uncommitted changes before planning.
Example fix
let plan = match absorption_plan_with_perm(ctx, AbsorptionTarget::Branch { branch_name: name.clone() }, perm) {
Err(e) if e.to_string().contains("No uncommitted changes assigned") => vec![], // nothing to do
other => other?,
}; Defensive patterns
Strategy: validation
Validate before calling
let changes = diff::changes_in_worktree_with_perm(
ctx,
ChangesSource::Head,
true,
perm.read_permission(),
)?;
let assigned: Vec<_> = changes
.assignments
.iter()
.filter(|a| a.stack_id == Some(stack_id))
.collect();
if assigned.is_empty() {
// skip absorb for this branch instead of calling the planner
} Try / catch
let plan = match absorption_plan_with_perm(ctx, AbsorptionTarget::Branch { branch_name }, perm) {
Err(e) if e.to_string().contains("No uncommitted changes assigned") => vec![], // nothing to do
other => other?,
}; Prevention
- Check hunk assignments for the branch before planning absorption.
- Guide users to assign hunks to the target branch first.
- Prefer the file-selection (TreeChanges) target when assignments are uncertain.
When it happens
Trigger: absorption_plan_with_perm(Branch) where worktree changes are all unassigned or assigned to other stacks, or the worktree is clean for that branch: candidates filtered by a.stack_id == Some(stack_id) come back empty.
Common situations: User forgot to drag/assign changes onto the branch in the UI; absorbing right after committing everything; assignments lost after a crash or workspace reset.
Related errors
- Branch not found: {branch_name}
- Stack has no ID
- Stack has no branches
- Unable to determine target commit for unassigned change: {}
- textFromToolResult(result)
AI-assisted analysis of gitbutlerapp/gitbutler@2497b8007a (2026-08-17).
Data as JSON: /api/errors/97bef06ed45c80d2.
Report an issue: GitHub.