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

  1. Refresh lazygit (r) — usually the merge/rebase state shown is stale and the option should not have been offered.
  2. If a merge/rebase really is expected, verify with 'git status' in a terminal (look for MERGE_HEAD or .git/rebase-merge).
  3. 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

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


AI-assisted analysis of jesseduffield/lazygit@c477a2959b (2026-08-15). Data as JSON: /api/errors/d04a203b827c81c7. Report an issue: GitHub.