{"record":{"id":"97bef06ed45c80d2","repo":"gitbutlerapp/gitbutler","slug":"no-uncommitted-changes-assigned-to-branch-branch","errorCode":null,"errorMessage":"No uncommitted changes assigned to branch: {branch_name}","messagePattern":"No uncommitted changes assigned to branch: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/but-api/src/legacy/absorb.rs","lineNumber":164,"sourceCode":"                .iter()\n                .find(|s| {\n                    s.heads\n                        .iter()\n                        .any(|h| h.name.to_str().map(|n| n == branch_name).unwrap_or(false))\n                })\n                .ok_or_else(|| anyhow::anyhow!(\"Branch not found: {branch_name}\"))?;\n\n            let stack_id = stack.id.ok_or_else(|| anyhow::anyhow!(\"Stack has no ID\"))?;\n\n            // Filter assignments to just this stack\n            let candidates: Vec<AbsorbCandidate> = all_assignments\n                .into_iter()\n                .filter(|a| a.stack_id == Some(stack_id))\n                .map(Into::into)\n                .collect();\n\n            if candidates.is_empty() {\n                anyhow::bail!(\"No uncommitted changes assigned to branch: {branch_name}\");\n            }\n\n            (candidates, dependencies)\n        }\n        AbsorptionTarget::TreeChanges {\n            changes,\n            assigned_stack_id,\n        } => {\n            // Get all worktree changes, assignments, and dependencies\n            let worktree_changes = crate::diff::changes_in_worktree_with_perm(\n                ctx,\n                ChangesSource::Head,\n                true,\n                perm.read_permission(),\n            )?;\n            let all_assignments = worktree_changes.assignments;\n            let dependencies = worktree_changes.dependencies;\n","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/2497b8007aa4a1922dae9a805b32ffe5b5037785/crates/but-api/src/legacy/absorb.rs#L146-L182","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"let plan = match absorption_plan_with_perm(ctx, AbsorptionTarget::Branch { branch_name: name.clone() }, perm) {\n    Err(e) if e.to_string().contains(\"No uncommitted changes assigned\") => vec![], // nothing to do\n    other => other?,\n};","handlingStrategy":"validation","validationCode":"let changes = diff::changes_in_worktree_with_perm(\n    ctx,\n    ChangesSource::Head,\n    true,\n    perm.read_permission(),\n)?;\nlet assigned: Vec<_> = changes\n    .assignments\n    .iter()\n    .filter(|a| a.stack_id == Some(stack_id))\n    .collect();\nif assigned.is_empty() {\n    // skip absorb for this branch instead of calling the planner\n}","typeGuard":null,"tryCatchPattern":"let plan = match absorption_plan_with_perm(ctx, AbsorptionTarget::Branch { branch_name }, perm) {\n    Err(e) if e.to_string().contains(\"No uncommitted changes assigned\") => vec![], // nothing to do\n    other => other?,\n};","preventionTips":["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."],"tags":["absorb","hunk-assignments","no-op","workspace"],"backgroundTag":"no-changes-assigned","analyzedSha":"2497b8007aa4a1922dae9a805b32ffe5b5037785","analyzedAt":"2026-08-17T00:30:25.648Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}