{"record":{"id":"46a19885d8fd722c","repo":"wagoodman/dive","slug":"unable-to-setup-tree-controller-w","errorCode":null,"errorMessage":"unable to setup tree controller: %w","messagePattern":"unable to setup tree controller: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/dive/cli/internal/ui/v1/view/filetree.go","lineNumber":486,"sourceCode":"\t} else {\n\t\tv.vm.ExpandLayout()\n\t}\n\n\tif v.vm.ShowAttributes {\n\t\tattributeRowSize = 1\n\t}\n\n\t// header + attribute header\n\theaderSize := 1 + attributeRowSize\n\t// note: maxY needs to account for the (invisible) border, thus a +1\n\theader, headerErr := g.SetView(v.Name()+\"header\", minX, minY, maxX, minY+headerSize+1, 0)\n\t// we are going to overlap the view over the (invisible) border (so minY will be one less than expected).\n\t// additionally, maxY will be bumped by one to include the border\n\tview, viewErr := g.SetView(v.Name(), minX, minY+headerSize, maxX, maxY+1, 0)\n\tif utils.IsNewView(viewErr, headerErr) {\n\t\terr := v.Setup(view, header)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"unable to setup tree controller: %w\", err)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (v *FileTree) RequestedSize(available int) *int {\n\t// var requestedWidth = int(float64(available) * (1.0 - v.requestedWidthRatio))\n\t// return &requestedWidth\n\treturn nil\n}\n","sourceCodeStart":468,"sourceCodeEnd":497,"githubUrl":"https://github.com/wagoodman/dive/blob/d6c691947f8fda635c952a17ee3b7555379d58f0/cmd/dive/cli/internal/ui/v1/view/filetree.go#L468-L497","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check the wrapped error text — keybinding conflicts say so explicitly; fix or remove the conflicting binding in dive.yaml / CLI flags","Re-run with default keybindings (--no.. config unset) to isolate the cause","Ensure adequate terminal width (>= 60 cols keeps the unconstrained layout path)","If forking, verify Setup's render path cannot run after gui.Close"],"exampleFix":"# dive.yaml — remove duplicate bindings that break FileTree.Setup\nkeybinding:\n  filetree:\n    toggle-collapse: [\"l\", \"arrowright\"]  # ensure no key is bound twice","handlingStrategy":"validation","validationCode":"// validate keybinding config before starting the UI\nseen := map[string]bool{}\nfor _, k := range cfg.Keys { if seen[k] { return fmt.Errorf(\"duplicate key: %s\", k) }; seen[k] = true }","typeGuard":null,"tryCatchPattern":"if err := v.Setup(view, header); err != nil {\n    return fmt.Errorf(\"unable to setup tree controller: %w\", err)\n}","preventionTips":["Lint dive.yaml keybindings for duplicates before launch","Keep terminal width >= 60 columns","Run with default config to bisect custom-config issues"],"tags":["ui","gocui","keybinding","filetree"],"backgroundTag":null,"analyzedSha":"d6c691947f8fda635c952a17ee3b7555379d58f0","analyzedAt":"2026-08-15T09:42:35.293Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}