jesseduffield/lazygit · warning

You cannot commit without a commit message

Error message

You cannot commit without a commit message

What it means

Thrown by CommitMessageController.setCommitMessageAtIndex when GetCommitMessageFromHistory(index) fails with an error other than ErrInvalidCommitIndex. lazygit tries to recall a previous commit message (from the repository's commit history or message history file) to prefill the commit message panel; any I/O or git failure other than 'index out of range' is reported as this generic 'cannot commit without a commit message' error, which mostly signals that the history source could not be read.

Source

Thrown at pkg/gui/controllers/commit_message_controller.go:167

	} else if currentIndex == context.NoCommitIndex {
		self.context().SetHistoryMessage(self.c.Helpers().Commits.JoinCommitMessageAndUnwrappedDescription())
	}

	validCommit, err := self.setCommitMessageAtIndex(newIndex)
	if validCommit {
		self.context().SetSelectedIndex(newIndex)
	}
	return err
}

// returns true if the given index is for a valid commit
func (self *CommitMessageController) setCommitMessageAtIndex(index int) (bool, error) {
	commitMessage, err := self.c.Git().Commit.GetCommitMessageFromHistory(index)
	if err != nil {
		if errors.Is(err, git_commands.ErrInvalidCommitIndex) {
			return false, nil
		}
		return false, errors.New(self.c.Tr.CommitWithoutMessageErr)
	}
	if self.c.UserConfig().Git.Commit.AutoWrapCommitMessage {
		commitMessage = helpers.TryRemoveHardLineBreaks(commitMessage, self.c.UserConfig().Git.Commit.AutoWrapWidth)
	}
	self.c.Helpers().Commits.SetMessageAndDescriptionInView(commitMessage)
	return true, nil
}

func (self *CommitMessageController) confirm() error {
	// The default keybinding for this action is "<enter>", which means that we
	// also get here when pasting multi-line text that contains newlines. In
	// that case we don't want to confirm the commit, but switch to the
	// description panel instead so that the rest of the pasted text goes there.
	//
	// Only do this if the SubmitEditorText command is actually mapped to
	// "<enter>" (the default). If it's not, we can only hope that it's mapped
	// to some ctrl key or fn key, which is unlikely to occur in pasted text.
	// And if they mapped some *other* command to "<enter>", then we're totally

View on GitHub (pinned to c477a2959b)

Solutions

  1. Check repository integrity: 'git fsck' and confirm .git is readable
  2. Simply type a commit message manually; the error only blocks the history-prefill path
  3. If it persists, inspect what GetCommitMessageFromHistory runs (git_commands) and reproduce it from the shell to see the underlying error
Defensive patterns

Strategy: fallback

Validate before calling

// Distinguish the expected sentinel from real read failures before surfacing an error:
msg, err := git.Commit.GetCommitMessageFromHistory(index)
if errors.Is(err, git_commands.ErrInvalidCommitIndex) {
    return false, nil // out-of-range index: benign
}
if err != nil {
    return false, err // real failure: report the underlying error, not a generic one
}

Try / catch

// errors.Is on the sentinel, generic fallback for the rest:
if err != nil {
    if errors.Is(err, git_commands.ErrInvalidCommitIndex) {
        return false, nil
    }
    return false, fmt.Errorf("reading commit message history: %w", err)
}

Prevention

When it happens

Trigger: Navigating the commit message history in the commit message panel (up/down through previous messages, or the keybinding that cycles recent commit messages) when reading the underlying history fails — e.g. the .git/COMMIT_EDITMSG or history source is unreadable, or the git invocation errored.

Common situations: Corrupted or permission-restricted git metadata, unusual repository layouts, or a race where the history file changed underneath the reader. Rarely seen in normal use.

Related errors


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