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
- Recompute the change descriptions from the source commit's current tree and retry
- Verify the specified changes actually exist in the source commit (paths and hunks)
- 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
- Re-derive change descriptions from the current tree, not cached state
- Refresh UI-captured hunks after any amend/rebase
- Verify paths and hunks exist in the source commit before moving
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
- Couldn't obtain diff for worktree changes.
- Deletions or additions aren't well-defined for hunk-based…
- Destination commit must not be conflicted
- Failed to apply changes to destination commit - merge…
- Failed to remove specified changes from commit
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)