jesseduffield/lazygit · error
Expected exactly one merge commit with hash %s
Error message
Expected exactly one merge commit with hash %s
What it means
Returned by dropMergeCommit when dropping a merge commit during a rebase: it looks for exactly one todo with command 'merge', flag '-C', and the given hash. If none or several match (typically zero, because the merge is recorded differently or already handled), the drop is refused since deleting the wrong line would corrupt the plan.
Source
Thrown at pkg/utils/rebase_todo.go:328
todos, err := ReadRebaseTodoFile(fileName, commentChar)
if err != nil {
return err
}
newTodos, err := dropMergeCommit(todos, hash)
if err != nil {
return err
}
return WriteRebaseTodoFile(fileName, newTodos, commentChar)
}
func dropMergeCommit(todos []todo.Todo, hash string) ([]todo.Todo, error) {
isMerge := func(t todo.Todo) bool {
return t.Command == todo.Merge && t.Flag == "-C" && equalHash(t.Commit, hash)
}
if lo.CountBy(todos, isMerge) != 1 {
return nil, fmt.Errorf("Expected exactly one merge commit with hash %s", hash)
}
_, idx, _ := lo.FindIndexOf(todos, isMerge)
return slices.Delete(todos, idx, idx+1), nil
}
View on GitHub (pinned to c477a2959b)
Solutions
- Open .git-rebase-todo and confirm a 'merge -C <hash>' line exists with the exact hash shown; edit manually if the encoding differs
- If the merge was already applied, refresh/restart the rebase view before dropping
- Upgrade git so rebase todos use the merge -C form lazygit expects
Defensive patterns
Strategy: validation
Validate before calling
# verify the exact merge line exists before dropping
grep -cE "^merge -C ${FULL_HASH}" .git/rebase-merge/git-rebase-todo # want exactly 1 Try / catch
Catch, show the expected 'merge -C <hash>' form to the user, and offer to open the todo file for manual editing instead of retrying blind.
Prevention
- Use a git version whose rebase todos record merges as 'merge -C <hash>'
- Confirm the merge is still pending in the todo before dropping it from lazygit
When it happens
Trigger: Dropping a merge commit from lazygit's commits view during an interactive rebase where the todo file lacks a 'merge -C <hash>' line for it (older git writing 'merge' differently, the merge already applied, or an externally edited todo).
Common situations: Rebases created by older git versions or other tools that don't emit 'merge -C'; attempting to drop a merge whose todo entry was already consumed; hash format mismatches (full vs abbreviated) in the todo file.
Related errors
- Todo %s not found in git-rebase-todo
- Expected exactly one original hash, found %d
- Expected exactly one fixup hash, found %d
- Cannot start interactive rebase: the HEAD commit is a merge
- index outside of range of commits
AI-assisted analysis of jesseduffield/lazygit@c477a2959b (2026-08-15).
Data as JSON: /api/errors/87435c8c71003f19.
Report an issue: GitHub.