gitbutlerapp/gitbutler · error

Failed to determine target commit for hunk absorption due…

Error message

Failed to determine target commit for hunk absorption due to ambiguous dependencies in path: {}

What it means

`ensure_target_commit` (part of hunk absorption via `group_changes_by_target_commit`) throws this when a hunk has hunk-level dependencies (locks) but no top-most lock can be determined in the workspace, so the commit that should receive the hunk is ambiguous. Absorption requires an unambiguous dependency path to decide which stack commit the hunk belongs to.

Solutions

  1. Refresh the workspace (`but pull` / re-open the project) so dependency locks are reconciled with current commits, then retry.
  2. Absorb the hunk into a specific commit explicitly (pick a target commit) instead of relying on automatic dependency resolution.
  3. Clear stale hunk dependencies for the file (re-assign the hunk) if the referenced commits are gone for good.

Example fix

// before
absorb_hunks(hunk)  // Err: ambiguous dependencies in path: src/lib.rs
// after
let target = pick_commit_explicitly(hunk.path);  // or refresh workspace first
absorb_hunks(hunk.into_target(target))
Defensive patterns

Strategy: fallback

Validate before calling

null

Type guard

null

Try / catch

try {
  await api.absorbHunks(hunks);
} catch (e) {
  if (String(e).includes('ambiguous dependencies in path')) {
    await api.refreshWorkspace();          // reconcile stale locks with current commits
    await api.absorbHunks(hunks, { explicitTarget: pickCommit(hunks) }); // or pick target manually
  } else throw e;
}

Prevention

When it happens

Trigger: Calling hunk absorption where `locks` is `Some` for the candidate hunk, `find_top_most_lock(locks, workspace)` returns `None` (the locked commits/branches are not present in the current workspace projection) and no stack assignment can be derived from the lock target.

Common situations: Hunk dependencies recorded against commits or branches that were since rebased away, squashed, or deleted; stale dependency metadata from an older workspace state; absorbing hunks whose reference commits no longer exist after a `but pull`.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18). Data as JSON: /api/errors/8b634d687408d920. Report an issue: GitHub.

Appendix: source

Thrown at crates/but-api/src/legacy/absorb.rs:424

fn ensure_target_commit(
    ctx: &mut Context,
    candidate: &AbsorbCandidate,
    locks: Option<&[HunkLock]>,
    workspace: &mut RefInfo,
    perm: &mut RepoExclusive,
) -> anyhow::Result<(
    but_core::ref_metadata::StackId,
    gix::ObjectId,
    AbsorptionReason,
)> {
    // Priority 1: Check if there's a dependency lock for this hunk
    if let Some(locks) = locks {
        if let Some(lock) = find_top_most_lock(locks, workspace) {
            if let HunkLockTarget::Stack(stack_id) = lock.target {
                return Ok((stack_id, lock.commit_id, AbsorptionReason::HunkDependency));
            }
        } else {
            anyhow::bail!(
                "Failed to determine target commit for hunk absorption due to ambiguous dependencies in path: {}",
                candidate.hunk.path
            );
        }
    }

    // Priority 2: Use the candidate's stack ID if available
    if let Some(stack_id) = candidate.stack_id {
        let branch_ref = candidate.branch_ref.as_ref();

        let (reference, commit_id) = target_segment(workspace, stack_id, branch_ref)?;
        if let Some(commit_id) = commit_id {
            return Ok((stack_id, commit_id, AbsorptionReason::StackAssignment));
        }

        // If there are no commits in the target branch, create a blank commit first
        commit_insert_blank_only_impl(
            ctx,

View on GitHub (pinned to 58e5313667)