{"record":{"id":"444023230d58d50d","repo":"jesseduffield/lazygit","slug":"gui-sidepanels-a-side-panel-must-have-at-least-on","errorCode":null,"errorMessage":"gui.sidePanels: a side panel must have at least one tab.","messagePattern":"gui\\.sidePanels: a side panel must have at least one tab\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/config/user_config_validation.go","lineNumber":72,"sourceCode":"\t}\n\tif err := validateCustomCommands(config.CustomCommands); err != nil {\n\t\treturn err\n\t}\n\tif err := validateSpinner(config.Gui.Spinner); err != nil {\n\t\treturn err\n\t}\n\tif err := validateSidePanels(config.Gui.SidePanels); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc validateSidePanels(panels []SidePanel) error {\n\tseen := map[string]bool{}\n\ttotal := 0\n\tfor _, panel := range panels {\n\t\tif len(panel) == 0 {\n\t\t\treturn errors.New(\"gui.sidePanels: a side panel must have at least one tab.\")\n\t\t}\n\t\tfor _, name := range panel {\n\t\t\tif !slices.Contains(ValidSidePanelTabs, name) {\n\t\t\t\treturn fmt.Errorf(\"gui.sidePanels: unknown side panel '%s'. Allowed values: %s\",\n\t\t\t\t\tname, strings.Join(ValidSidePanelTabs, \", \"))\n\t\t\t}\n\t\t\tif seen[name] {\n\t\t\t\treturn fmt.Errorf(\"gui.sidePanels: '%s' is listed more than once; each side panel may appear only once.\", name)\n\t\t\t}\n\t\t\tseen[name] = true\n\t\t\ttotal++\n\t\t}\n\t}\n\tif total == 0 {\n\t\treturn errors.New(\"gui.sidePanels must not be empty.\")\n\t}\n\t// A lot of code focuses these panels directly (e.g. after resolving a\n\t// conflict or popping a stash), so they must always be present; otherwise","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/jesseduffield/lazygit/blob/c477a2959b229fbf3284be0d4d2904ab61ec3c94/pkg/config/user_config_validation.go#L54-L90","documentation":"Validation error from validateSidePanels in pkg/config/user_config_validation.go:72. gui.sidePanels is a list of side panels, each itself a list of tab names; an inner list with zero entries means a side panel with no tabs, which lazygit cannot render. The check rejects it at config load time.","triggerScenarios":"Writing gui.sidePanels with an empty inner list, e.g. 'sidePanels: [[commits, files], []]' — the second panel has no tabs. Loading the config triggers validateSidePanels which returns this error before the GUI starts.","commonSituations":"Restructuring sidePanels to hide panels and accidentally leaving an empty group; YAML indentation mistakes that parse a panel as empty; config generated by scripts.","solutions":["Open config.yml, find gui.sidePanels, and give every inner list at least one valid tab name","Remove the empty inner list entirely if the panel is not wanted","Cross-check names against ValidSidePanelTabs (the error for unknown names lists them) and restart lazygit"],"exampleFix":"# before\ngui:\n  sidePanels:\n    - [commits, files]\n    - []\n\n# after\ngui:\n  sidePanels:\n    - [commits, files]\n    - [branches]","handlingStrategy":"validation","validationCode":"function validateSidePanelsDraft(panels [][]string) error {\n    for _, panel := range panels {\n        if len(panel) == 0 {\n            return errors.New(\"a side panel must have at least one tab\")\n        }\n    }\n    return nil\n}","typeGuard":"func isNonEmptySidePanel(p []string) bool { return len(p) > 0 }","tryCatchPattern":null,"preventionTips":["After editing sidePanels, mentally check every inner list has a tab","Prefer deleting an unwanted panel over leaving it empty","Keep names from the documented tab vocabulary"],"tags":["config","yaml","validation","gui"],"backgroundTag":null,"analyzedSha":"c477a2959b229fbf3284be0d4d2904ab61ec3c94","analyzedAt":"2026-08-15T08:34:32.451Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}