wagoodman/dive · error

unable to setup tree controller: %w

Error message

unable to setup tree controller: %w

What it means

Raised in the filetree view's Layout when FileTree.Setup fails on first-time view creation (utils.IsNewView true for the 'filetree'/'filefileheader' views). Setup configures the view, registers keybindings, and triggers an initial render; any of those failing produces this wrap. This is the right-hand pane showing the layer's file tree.

Source

Thrown at cmd/dive/cli/internal/ui/v1/view/filetree.go:486

	} else {
		v.vm.ExpandLayout()
	}

	if v.vm.ShowAttributes {
		attributeRowSize = 1
	}

	// header + attribute header
	headerSize := 1 + attributeRowSize
	// note: maxY needs to account for the (invisible) border, thus a +1
	header, headerErr := g.SetView(v.Name()+"header", minX, minY, maxX, minY+headerSize+1, 0)
	// we are going to overlap the view over the (invisible) border (so minY will be one less than expected).
	// additionally, maxY will be bumped by one to include the border
	view, viewErr := g.SetView(v.Name(), minX, minY+headerSize, maxX, maxY+1, 0)
	if utils.IsNewView(viewErr, headerErr) {
		err := v.Setup(view, header)
		if err != nil {
			return fmt.Errorf("unable to setup tree controller: %w", err)
		}
	}
	return nil
}

func (v *FileTree) RequestedSize(available int) *int {
	// var requestedWidth = int(float64(available) * (1.0 - v.requestedWidthRatio))
	// return &requestedWidth
	return nil
}

View on GitHub (pinned to d6c691947f)

Solutions

  1. Check the wrapped error text — keybinding conflicts say so explicitly; fix or remove the conflicting binding in dive.yaml / CLI flags
  2. Re-run with default keybindings (--no.. config unset) to isolate the cause
  3. Ensure adequate terminal width (>= 60 cols keeps the unconstrained layout path)
  4. If forking, verify Setup's render path cannot run after gui.Close

Example fix

# dive.yaml — remove duplicate bindings that break FileTree.Setup
keybinding:
  filetree:
    toggle-collapse: ["l", "arrowright"]  # ensure no key is bound twice
Defensive patterns

Strategy: validation

Validate before calling

// validate keybinding config before starting the UI
seen := map[string]bool{}
for _, k := range cfg.Keys { if seen[k] { return fmt.Errorf("duplicate key: %s", k) }; seen[k] = true }

Try / catch

if err := v.Setup(view, header); err != nil {
    return fmt.Errorf("unable to setup tree controller: %w", err)
}

Prevention

When it happens

Trigger: g.SetView succeeding for the filetree views but FileTree.Setup(view, header) erroring: keybinding registration failures (duplicate/conflicting keys), or the initial vm Update/Render failing, e.g. writing to the buffer or an underlying viewmodel error.

Common situations: Custom keybinding configs in dive.yaml that bind the same key twice; terminal resized to a width < 60 triggering ConstrainLayout during setup; races between gui teardown and first layout; very long filter regexes or malformed state at startup.

Related errors


AI-assisted analysis of wagoodman/dive@d6c691947f (2026-08-15). Data as JSON: /api/errors/46a19885d8fd722c. Report an issue: GitHub.