{"record":{"id":"2824f515428ee41c","repo":"wailsapp/wails","slug":"unknown-menu-type-for-newmenuitemimpl-v","errorCode":null,"errorMessage":"Unknown menu type for newMenuItemImpl: %v","messagePattern":"Unknown menu type for newMenuItemImpl: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/pkg/application/menuitem_linux.go","lineNumber":94,"sourceCode":"\tif accelerator == nil || l.menuItem == nil {\n\t\treturn\n\t}\n\tInvokeSync(func() {\n\t\tsetMenuItemAccelerator(l.menuItem.id, accelerator)\n\t})\n}\n\nfunc newMenuItemImpl(item *MenuItem) *linuxMenuItem {\n\tresult := &linuxMenuItem{\n\t\tmenuItem: item,\n\t}\n\tswitch item.itemType {\n\tcase text:\n\t\tresult.native = menuItemNewWithId(item.label, item.bitmap, item.id)\n\tcase submenu:\n\t\tresult.native = menuItemNewWithId(item.label, item.bitmap, item.id)\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"Unknown menu type for newMenuItemImpl: %v\", item.itemType))\n\t}\n\tif item.accelerator != nil {\n\t\tresult.setAccelerator(item.accelerator)\n\t}\n\tresult.setDisabled(result.menuItem.disabled)\n\treturn result\n}\n\nfunc newCheckMenuItemImpl(item *MenuItem) *linuxMenuItem {\n\tresult := &linuxMenuItem{\n\t\tmenuItem: item,\n\t\tnative:   menuCheckItemNewWithId(item.label, item.bitmap, item.id, item.checked),\n\t}\n\tif item.accelerator != nil {\n\t\tresult.setAccelerator(item.accelerator)\n\t}\n\tresult.setDisabled(result.menuItem.disabled)\n\treturn result","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/wailsapp/wails/blob/0e754b1b40ba9044c2a1460e23b7c3de20fc5cf3/v3/pkg/application/menuitem_linux.go#L76-L112","documentation":"newMenuItemImpl (v3/pkg/application/menuitem_linux.go:94) is the GTK4 Linux factory that turns a generic MenuItem into a native linuxMenuItem. It only handles itemType text and submenu; the menuItemType enum (menuitem.go:11-16) also defines separator, checkbox and radio, and any other value falls into default: and panics. checkbox and radio items are routed to their own factories (newCheckMenuItemImpl / newRadioItemImpl) by menu_linux.go's processMenu switch, so in practice this panic means a MenuItem whose itemType is separator (or an out-of-range value) reached the generic text/submenu factory.","triggerScenarios":"Adding a Menu.AddSeparator() item on Linux GTK4 and having it dispatched as a normal item (separator is skipped in processMenu only when the menu uses sections, so non-section menus with separators can hit it); constructing a MenuItem with a zero or corrupted itemType; new code paths that call newMenuItemImpl directly without first switching on item.itemType; radio/checkbox items misrouted through the generic factory.","commonSituations":"Building the same Menu tree for Windows/macOS and Linux where separators work on the former; GTK4 port work (v3's default Linux stack since the GTK4 default-flip) where separator support is incomplete; copying menu construction from GTK3-tagged code into the GTK4 path; unit tests that exercise menu item factories directly.","solutions":["In processMenu (menu_linux.go), make sure separator items are handled by their own case before any call to newMenuItemImpl; on GTK4, map separators to menuNewSection or skip them like menuitem_linux_gtk3.go does.","If you control the factory, extend newMenuItemImpl's switch with a separator case (e.g. result.native = menuItemNewSeparator()) instead of letting it hit default.","Audit menu construction code for items created without going through NewMenuItem/NewSubMenuItem/NewCheckMenuItem/NewRadioMenuItem/NewSeparator — hand-rolled MenuItem{} literals leave itemType unset (text=0 is fine, but any drift breaks).","Reproduce with GOFLAGS left at default (GTK4 build) and, if the menu works only with -tags gtk3, file a Wails issue noting the GTK4 gap."],"exampleFix":"// before (menuitem_linux.go)\nfunc newMenuItemImpl(item *MenuItem) *linuxMenuItem {\n\tswitch item.itemType {\n\tcase text:\n\t\tresult.native = menuItemNewWithId(item.label, item.bitmap, item.id)\n\tcase submenu:\n\t\tresult.native = menuItemNewWithId(item.label, item.bitmap, item.id)\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"Unknown menu type for newMenuItemImpl: %v\", item.itemType))\n\t}\n\t...\n}\n\n// after\nfunc newMenuItemImpl(item *MenuItem) *linuxMenuItem {\n\tswitch item.itemType {\n\tcase text, submenu:\n\t\tresult.native = menuItemNewWithId(item.label, item.bitmap, item.id)\n\tcase separator:\n\t\tresult.native = menuItemNewSeparator()\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"Unknown menu type for newMenuItemImpl: %v\", item.itemType))\n\t}\n\t...\n}","handlingStrategy":"validation","validationCode":"// Before attaching a menu on GTK4 Linux, check every item's type\n// is one the factories support via the generic path.\nfunc menuItemsSupportedGTK4(m *app.Menu) bool {\n\tsupported := true\n\tm.Visit(func(item *app.MenuItem) { // or walk your own item slice\n\t\t// text and submenu are safe; checkbox/radio route to their\n\t\t// own factories; separator is the risky one on GTK4\n\t})\n\treturn supported\n}\n\n// Simplest guard: only add separators when sections are not used.\nif runtime.GOOS == \"linux\" {\n\t// omit AddSeparator() or verify your Wails version supports it\n}","typeGuard":"// Narrowing helper for the menuItemType values defined in menuitem.go\ntype menuItemKind int\n\nfunc kindOf(itemType menuItemKind) string {\n\tswitch itemType {\n\tcase 0: return \"text\"\n\tcase 1: return \"separator\"\n\tcase 2: return \"checkbox\"\n\tcase 3: return \"radio\"\n\tcase 4: return \"submenu\"\n\tdefault: return \"unknown\"\n\t}\n}","tryCatchPattern":"// Go: guard menu construction so a factory panic doesn't kill the app\ndefer func() {\n\tif r := recover(); r != nil {\n\t\tlog.Printf(\"menu build failed: %v\", r)\n\t}\n}()\nmenu := app.NewMenu()","preventionTips":["Create menu items only via NewMenuItem/NewSubMenuItem/NewCheckMenuItem/NewRadioMenuItem/NewSeparator — never MenuItem{} literals.","Test menus on the GTK4 Linux build (default) in CI, not only on Windows/macOS.","Keep Wails updated — the GTK4 menu implementation is actively completed upstream.","Watch for separator-heavy menus when porting GTK3-era code to the GTK4 path."],"tags":["linux","gtk4","menus","panic","not-implemented"],"backgroundTag":null,"analyzedSha":"0e754b1b40ba9044c2a1460e23b7c3de20fc5cf3","analyzedAt":"2026-08-15T14:17:36.034Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}