{"record":{"id":"e5bc082e58a90532","repo":"wagoodman/dive","slug":"failed-to-layout-q-footer-w","errorCode":null,"errorMessage":"failed to layout %q footer: %w","messagePattern":"failed to layout %q footer: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/dive/cli/internal/ui/v1/layout/manager.go","lineNumber":167,"sourceCode":"\t// layout footers top down (which is why the list is reversed). Top down is needed due to border overlap.\n\tif elements, exists := lm.elements[LocationFooter]; exists {\n\t\tfor idx := len(elements) - 1; idx >= 0; idx-- {\n\t\t\telement := elements[idx]\n\t\t\theight := footerHeights[idx]\n\t\t\tvar topY, bottomY, bottomPadding int\n\t\t\tfor oIdx := 0; oIdx <= idx; oIdx++ {\n\t\t\t\tbottomPadding += footerHeights[oIdx]\n\t\t\t}\n\t\t\ttopY = area.maxY - bottomPadding - height\n\t\t\t// +1 for border\n\t\t\tbottomY = topY + height + 1\n\n\t\t\t// layout the footer within the allocated space\n\t\t\t// note: since the headers and rows are inclusive counting from -1 (to account for a border) we must\n\t\t\t// do the same vertically, thus a -1 is needed for a starting Y\n\t\t\terr := element.Layout(g, area.minX, topY, area.maxX, bottomY)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to layout %q footer: %w\", element.Name(), err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (lm *Manager) notifyLayoutChange() error {\n\tfor _, elements := range lm.elements {\n\t\tfor _, element := range elements {\n\t\t\terr := element.OnLayoutChange()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/wagoodman/dive/blob/d6c691947f8fda635c952a17ee3b7555379d58f0/cmd/dive/cli/internal/ui/v1/layout/manager.go#L149-L185","documentation":"The layout Manager wraps failures of footer elements' Layout calls (the status bar and, in debug mode, other footer panes laid out bottom-up with border padding). The %q is the footer element name (typically \"status\" or \"debug\"). The wrapped error comes from that footer's gocui SetView or its controller Setup.","triggerScenarios":"A footer element's Layout failing when g.SetView is called with the computed topY/bottomY: negative or inverted Y coordinates when the terminal is too short for the stacked footer heights, or the footer controller's Setup returning an error on first creation.","commonSituations":"Terminal height too small to fit main content plus footer rows; resizing to near-zero height triggers layout; multiple footers whose combined heights (footerHeights) exceed area.maxY; a footer Setup failing (e.g. debug view write errors).","solutions":["Increase terminal height so footers fit below the main rows","Inspect the wrapped error for the specific footer and fix that (usually the status view)","Avoid running dive in embedded terminals with fewer than ~10 rows","If embedding, clamp footerHeights so their sum stays under area.maxY"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// skip footer layout when there is no vertical room left\ntotalFooter := 0\nfor _, h := range footerHeights { totalFooter += h }\nif area.maxY-area.minY <= totalFooter { return nil }","typeGuard":null,"tryCatchPattern":"if err := lm.layoutFooters(g, area, footerHeights); err != nil {\n    return fmt.Errorf(\"footer layout failed: %w\", err)\n}","preventionTips":["Keep footer count and heights minimal","Clamp footerHeights so their sum is far below the screen height","Unit-test layout with degenerate areas (maxY==minY)"],"tags":["ui","gocui","layout","footer"],"backgroundTag":null,"analyzedSha":"d6c691947f8fda635c952a17ee3b7555379d58f0","analyzedAt":"2026-08-15T09:42:35.293Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}