gitbutlerapp/gitbutler · error

Failed to extract described changes from source commit

Error message

Failed to extract described changes from source commit

What it means

After building a source tree with the requested changes removed, some of the described diffs were not found in the source commit, so the extraction is incomplete. The library bails rather than silently producing a source commit that still contains (part of) the changes.

Solutions

  1. Recompute the change descriptions from the source commit's current tree and retry
  2. Verify the specified changes actually exist in the source commit (paths and hunks)
  3. If partial extraction is acceptable, split the request into individually-verified changes

Example fix

// before
editor.move_changes_between_commits(src, dst, stale_changes, ctx)?;
// after
let fresh = describe_changes_from(src, repo)?; // re-derive from current tree
editor.move_changes_between_commits(src, dst, fresh, ctx)?;
Defensive patterns

Strategy: validation

Validate before calling

// ensure the described changes exist in the source commit before moving
for change in &changes_to_move {
    assert_change_present_in(change, source_commit_tree)?;
}

Try / catch

match editor.move_changes_between_commits(src, dst, changes, ctx) {
    Err(e) if e.to_string().contains("Failed to extract described changes") => refresh_descriptions_and_retry(),
    other => other,
}

Prevention

When it happens

Trigger: move_changes_between_commits is called with changes_to_move that don't exactly match hunks present in the source commit's tree (stale file paths, wrong line ranges, changes already moved out).

Common situations: UI state was captured before the commit changed (e.g. an amend or rebase shifted the diffs); describing changes by file/line after the file was edited elsewhere.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at crates/but-workspace/src/commit/move_changes.rs:82

    let source_tree_id = {
        let source_commit = source_commit.clone().attach(editor.repo());
        if source_commit.is_conflicted() {
            bail!("Source commit must not be conflicted")
        }
        source_commit.tree
    };

    let (source_tree_without_changes_id, dropped_diffs) = create_tree_without_diff(
        editor.repo(),
        ChangesSource::Commit {
            id: source_commit.id,
        },
        changes_to_move,
        context_lines,
    )?;

    if !dropped_diffs.is_empty() {
        bail!("Failed to extract described changes from source commit");
    }

    let new_source_commit_id = {
        let mut new_source_commit = source_commit.clone();
        new_source_commit.tree = source_tree_without_changes_id;
        editor.new_commit(new_source_commit, DateMode::CommitterUpdateAuthorKeep)?
    };

    editor.replace(source_selector, Step::new_pick(new_source_commit_id))?;

    // Rebase and get potentially rebased destination commit
    let mut editor = editor.rebase()?.into_editor();
    let (_, rebased_destination_commit) = editor.find_selectable_commit(destination_selector)?;
    let destination_tree_id = {
        let rebased_destination_commit = rebased_destination_commit.clone().attach(editor.repo());
        if rebased_destination_commit.is_conflicted() {
            bail!("Destination commit must not be conflicted")
        }

View on GitHub (pinned to 58e5313667)