{"record":{"id":"3225b474e2f7cbd0","repo":"gitbutlerapp/gitbutler","slug":"unable-to-determine-target-commit-for-unassigned-c","errorCode":null,"errorMessage":"Unable to determine target commit for unassigned change: {}","messagePattern":"Unable to determine target commit for unassigned change: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-api/src/legacy/absorb.rs","lineNumber":498,"sourceCode":"            ctx,\n            RelativeTo::Reference(branch.reference.clone()),\n            InsertSide::Below,\n            DryRun::No,\n            perm,\n        )?;\n\n        // Now fetch the stack details again to get the newly created commit\n        let stack_details = crate::legacy::workspace::stack_details(ctx, Some(stack_id))?;\n        if let Some(branch) = stack_details.branch_details.first()\n            && let Some(commit) = branch.commits.first()\n        {\n            return Ok((stack_id, commit.id, AbsorptionReason::DefaultStack));\n        }\n\n        anyhow::bail!(\"Failed to create blank commit in leftmost stack\");\n    }\n\n    anyhow::bail!(\n        \"Unable to determine target commit for unassigned change: {}\",\n        candidate.hunk.path\n    );\n}\n\n/// Prepare commit absorptions with commit summaries\n///\n/// This returns a vector of absorption information, sorted and ready for processing.\nfn prepare_commit_absorptions(\n    ctx: &Context,\n    changes_by_commit: GroupedChanges,\n) -> anyhow::Result<Vec<CommitAbsorption>> {\n    let mut commit_absorptions = Vec::new();\n\n    // Cache the stack details to determine the commit order\n    let mut stack_details_map = HashMap::<StackId, StackDetails>::new();\n    let all_stack_ids = changes_by_commit\n        .keys()","sourceCodeStart":480,"sourceCodeEnd":516,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/2497b8007aa4a1922dae9a805b32ffe5b5037785/crates/but-api/src/legacy/absorb.rs#L480-L516","documentation":"Final fallback in ensure_target_commit(): for an unassigned change with no dependency locks and no usable stack, workspace::stacks() yielded no stack with an id (or an empty list) — there is no destination commit to absorb into, so the operation fails for the candidate's path.","triggerScenarios":"absorption_plan/absorb with unassigned hunks while the workspace has zero stacks: a freshly initialized project with no virtual branch created yet, or after all stacks were unapplied or deleted.","commonSituations":"New project where the user has not created a first stack; scripts or tests calling absorb without workspace setup; workspace after deleting every stack.","solutions":["Create or apply at least one stack first, then retry the absorb","If stacks should exist, reload the workspace and check metadata persistence","Guard UI/SDK flows: only offer absorb when at least one applied stack exists"],"exampleFix":"// before\nlet plan = absorption_plan(ctx, AbsorptionTarget::All)?;\n\n// after: ensure a destination stack exists\nlet stacks = workspace_stacks(ctx)?;\nif stacks.iter().all(|s| s.id.is_none()) {\n    create_or_apply_first_stack(ctx)?; // e.g. create a stack from the current HEAD\n}\nlet plan = absorption_plan(ctx, AbsorptionTarget::All)?;","handlingStrategy":"validation","validationCode":"let stacks = workspace_stacks(ctx)?;\nlet absorb_possible = stacks.iter().any(|s| s.id.is_some());\nif !absorb_possible {\n    // create/apply a stack first; otherwise absorb of unassigned hunks will fail\n}","typeGuard":"fn workspace_can_absorb(stacks: &[StackSummary]) -> bool {\n    stacks.iter().any(|s| s.id.is_some())\n}","tryCatchPattern":"match absorption_plan(ctx, AbsorptionTarget::All) {\n    Err(err) if err.to_string().contains(\"Unable to determine target commit for unassigned change\") => {\n        // create or apply a stack, then re-run the plan\n    }\n    other => other,\n}","preventionTips":["Ensure at least one applied stack exists before exposing absorb actions","In tests/SDK scripts, set up a workspace stack before absorbing","Treat zero-stack workspaces as a precondition failure, not an absorb error"],"tags":["git","absorb","workspace","stacks","empty-state"],"backgroundTag":"no-target-branch","analyzedSha":"2497b8007aa4a1922dae9a805b32ffe5b5037785","analyzedAt":"2026-08-17T00:30:25.648Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}