gitbutlerapp/gitbutler · error
Unable to determine target commit for unassigned change: {}
Error message
Unable to determine target commit for unassigned change: {} What it means
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.
Source
Thrown at crates/but-api/src/legacy/absorb.rs:498
ctx,
RelativeTo::Reference(branch.reference.clone()),
InsertSide::Below,
DryRun::No,
perm,
)?;
// Now fetch the stack details again to get the newly created commit
let stack_details = crate::legacy::workspace::stack_details(ctx, Some(stack_id))?;
if let Some(branch) = stack_details.branch_details.first()
&& let Some(commit) = branch.commits.first()
{
return Ok((stack_id, commit.id, AbsorptionReason::DefaultStack));
}
anyhow::bail!("Failed to create blank commit in leftmost stack");
}
anyhow::bail!(
"Unable to determine target commit for unassigned change: {}",
candidate.hunk.path
);
}
/// Prepare commit absorptions with commit summaries
///
/// This returns a vector of absorption information, sorted and ready for processing.
fn prepare_commit_absorptions(
ctx: &Context,
changes_by_commit: GroupedChanges,
) -> anyhow::Result<Vec<CommitAbsorption>> {
let mut commit_absorptions = Vec::new();
// Cache the stack details to determine the commit order
let mut stack_details_map = HashMap::<StackId, StackDetails>::new();
let all_stack_ids = changes_by_commit
.keys()View on GitHub (pinned to 2497b8007a)
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
Example fix
// before
let plan = absorption_plan(ctx, AbsorptionTarget::All)?;
// after: ensure a destination stack exists
let stacks = workspace_stacks(ctx)?;
if stacks.iter().all(|s| s.id.is_none()) {
create_or_apply_first_stack(ctx)?; // e.g. create a stack from the current HEAD
}
let plan = absorption_plan(ctx, AbsorptionTarget::All)?; Defensive patterns
Strategy: validation
Validate before calling
let stacks = workspace_stacks(ctx)?;
let absorb_possible = stacks.iter().any(|s| s.id.is_some());
if !absorb_possible {
// create/apply a stack first; otherwise absorb of unassigned hunks will fail
} Type guard
fn workspace_can_absorb(stacks: &[StackSummary]) -> bool {
stacks.iter().any(|s| s.id.is_some())
} Try / catch
match absorption_plan(ctx, AbsorptionTarget::All) {
Err(err) if err.to_string().contains("Unable to determine target commit for unassigned change") => {
// create or apply a stack, then re-run the plan
}
other => other,
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: New project where the user has not created a first stack; scripts or tests calling absorb without workspace setup; workspace after deleting every stack.
Related errors
- Branch not found: {branch_name}
- Stack has no ID
- Stack has no branches
- No stacks found in the workspace
- No uncommitted changes assigned to branch: {branch_name}
AI-assisted analysis of gitbutlerapp/gitbutler@2497b8007a (2026-08-17).
Data as JSON: /api/errors/3225b474e2f7cbd0.
Report an issue: GitHub.