jesseduffield/lazygit · warning
You are currently neither rebasing nor merging
Error message
You are currently neither rebasing nor merging
What it means
Returned by MergeAndRebaseHelper.genericMergeCommandImpl when an abort/continue/skip-style merge-or-rebase command is requested but WorkingTreeState() reports neither a merge nor a rebase in progress (status.None()). The function is the single funnel for generic 'git merge/--continue/--abort' and 'git rebase --continue/--abort/--skip' dispatch, so it guards up front that a state machine actually exists to act on.
Source
Thrown at pkg/gui/controllers/helpers/merge_and_rebase_helper.go:101
// spin up a worker (via the waiting status below) to do the actual work.
return self.genericMergeCommandImpl(command, true, false)
}
// genericMergeCommandImpl runs a merge/rebase continue/skip/abort and handles
// the result. Continuing can be slow (it may replay many commits), so the
// non-subprocess path runs on a worker with a waiting status.
//
// showWaitingStatus is false only for the recursive auto-skip in
// CheckMergeOrRebaseWithRefreshOptions, which already runs on a worker, so it
// must not spin up a second waiting status. calledFromWorker is used only by the
// subprocess path below: it's true for that recursive worker skip and false for
// genericMergeCommand's UI-thread invocation, so the post-action refresh picks
// RefreshFromWorker vs Refresh correctly.
func (self *MergeAndRebaseHelper) genericMergeCommandImpl(command string, showWaitingStatus bool, calledFromWorker bool) error {
status := self.c.Git().Status.WorkingTreeState()
if status.None() {
return errors.New(self.c.Tr.NotMergingOrRebasing)
}
self.c.LogAction(fmt.Sprintf("Merge/Rebase: %s", command))
effectiveStatus := status.Effective()
if effectiveStatus == models.WORKING_TREE_STATE_REBASING {
todoFile, err := os.ReadFile(
filepath.Join(self.c.Git().RepoPaths.WorktreeGitDirPath(), "rebase-merge/git-rebase-todo"),
)
if err != nil {
if !os.IsNotExist(err) {
return err
}
} else {
self.c.LogCommand(string(todoFile), false)
}
}
View on GitHub (pinned to c477a2959b)
Solutions
- Refresh lazygit (r) — usually the merge/rebase state shown is stale and the option should not have been offered.
- If a merge/rebase really is expected, verify with 'git status' in a terminal (look for MERGE_HEAD or .git/rebase-merge).
- If genuinely finished, just proceed with normal work; there is nothing to continue or abort.
Defensive patterns
Strategy: validation
Validate before calling
// guard before invoking continue/abort/skip:
if self.c.Git().Status.WorkingTreeState().None() {
// state already resolved: refresh instead of dispatching a generic command
} Prevention
- Refresh (r) after finishing a rebase externally before using conflict keys
- Avoid double-pressing continue; wait for the refresh between presses
When it happens
Trigger: Pressing the continue/abort/skip merge-rebase keybindings (e.g. 'm' menu options or 'M' conflicts keys) after the merge/rebase already finished — typically because another process, an auto-refresh race, or the user completed it elsewhere — leaving no MERGE_HEAD or rebase-merge directory.
Common situations: Stale UI after a rebase finished in a terminal; race where lazygit's status refresh lags the actual repo state; double-pressing continue; a worktree where the rebase was aborted externally.
Related errors
- Cannot merge branch in detached head state. You might have c
- You cannot merge a branch into itself
- Todo %s not found in git-rebase-todo
- Git version must be at least %s. Please upgrade your git ver
- Lazygit does not support bare repos.
AI-assisted analysis of jesseduffield/lazygit@c477a2959b (2026-08-15).
Data as JSON: /api/errors/d04a203b827c81c7.
Report an issue: GitHub.