jesseduffield/lazygit · error

Cannot stage/unstage directory containing files with inline

Error message

Cannot stage/unstage directory containing files with inline merge conflicts. Please fix up the merge conflicts first

What it means

Thrown by FilesController.toggleStaged when any node in the selection subtree has inline merge-conflict markers. Staging or unstaging a directory containing unresolved conflict files would literally stage the '<<<<<<<'/'======='/'>>>>>>>' marker lines into the index, corrupting the merge resolution, so lazygit refuses until conflicts are resolved.

Source

Thrown at pkg/gui/controllers/files_controller.go:519

// callbacks. press() (acting on the selection) and toggleStagedAll() (acting on
// the whole tree) share this; they differ only in the git commands they run,
// which is why those are passed in.
//
// If any node has unstaged changes we stage the nodes that have them (staging
// already-staged deleted files/folders would fail); otherwise we unstage all
// the nodes.
func (self *FilesController) toggleStaged(
	nodes []*filetree.FileNode,
	stageAction string,
	unstageAction string,
	stage func(unstagedNodes []*filetree.FileNode) error,
	unstage func(nodes []*filetree.FileNode) error,
) error {
	for _, node := range nodes {
		// if any files within have inline merge conflicts we can't stage or unstage,
		// or it'll end up with those >>>>>> lines actually staged
		if node.GetHasInlineMergeConflicts() {
			return errors.New(self.c.Tr.ErrStageDirWithInlineMergeConflicts)
		}
	}

	nodes = normalisedSelectedNodes(nodes)

	unstagedNodes := filterNodesHaveUnstagedChanges(nodes, self.c.Model().Submodules)

	// Staging a submodule that only has dirty or untracked content (no new
	// commit) is a no-op: the parent repo can't stage that content. When that's
	// the only thing that looks stageable, don't stage; fall through to
	// unstaging instead. That keeps the toggle symmetric (e.g. a fully-staged
	// tree that also contains a dirty submodule still unstages on the next
	// press) rather than getting stuck trying to stage the unstageable content.
	shouldStage := len(unstagedNodes) > 0
	if shouldStage {
		noOp, err := self.stagingWouldBeNoOp(unstagedNodes)
		if err != nil {
			return err

View on GitHub (pinned to c477a2959b)

Solutions

  1. Enter the conflicted files (navigate + enter, or the merge-conflicts view) and resolve the markers
  2. Stage each resolved file individually once conflicts are fixed
  3. If you want to take one side wholesale, use the checkout-ours/theirs option on the conflicted file, then stage
Defensive patterns

Strategy: validation

Validate before calling

// Reject staging when any node in the selection carries conflict markers:
for _, node := range nodes {
    if node.GetHasInlineMergeConflicts() {
        return errors.New("resolve merge conflicts before staging this path")
    }
}

Prevention

When it happens

Trigger: Pressing 'space' (stage/unstage toggle) on a directory (or multi-node selection) that contains at least one file in a conflicted, unresolved merge/rebase/cherry-pick state.

Common situations: Mid-merge with conflicts in several files under one directory; users try to stage the whole directory to 'get it over with' without resolving markers first.

Related errors


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