{"record":{"id":"9dbed99aa99cdda3","repo":"wailsapp/wails","slug":"radiogroup-menuid-item-not-found","errorCode":null,"errorMessage":"RadioGroup.MenuID: item not found:","messagePattern":"RadioGroup\\.MenuID: item not found:","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/pkg/application/popupmenu_windows.go","lineNumber":43,"sourceCode":"func (r *RadioGroup) Add(id int, item *MenuItem) {\n\t*r = append(*r, &RadioGroupMember{\n\t\tID:       id,\n\t\tMenuItem: item,\n\t})\n}\n\nfunc (r *RadioGroup) Bounds() (int, int) {\n\tp := *r\n\treturn p[0].ID, p[len(p)-1].ID\n}\n\nfunc (r *RadioGroup) MenuID(item *MenuItem) int {\n\tfor _, member := range *r {\n\t\tif member.MenuItem == item {\n\t\t\treturn member.ID\n\t\t}\n\t}\n\tpanic(\"RadioGroup.MenuID: item not found:\")\n}\n\ntype Win32Menu struct {\n\tisPopup       bool\n\tmenu          w32.HMENU\n\tparentWindow  *windowsWebviewWindow\n\tparent        w32.HWND\n\tmenuMapping   map[int]*MenuItem\n\tcheckboxItems map[*MenuItem][]int\n\tradioGroups   map[*MenuItem][]*RadioGroup\n\tmenuData      *Menu\n\tcurrentMenuID int\n\tonMenuClose   func()\n\tonMenuOpen    func()\n\tisShowing     atomic.Bool // guards against concurrent TrackPopupMenuEx calls\n\n\t// bitmaps tracks HBITMAP handles allocated by SetMenuIcons during\n\t// buildMenu so they can be released when the menu is rebuilt or","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/wailsapp/wails/blob/0e754b1b40ba9044c2a1460e23b7c3de20fc5cf3/v3/pkg/application/popupmenu_windows.go#L25-L61","documentation":"RadioGroup.MenuID panics when asked for the Win32 command ID of a radio menu item that is not a member of that radio group. It is called from Win32Menu.updateRadioGroup (popupmenu_windows.go:425), which runs whenever a checked radio item is updated (UpdateMenuItem / SetChecked). The panic signals an internal bookkeeping mismatch: the item was checked before the popup menu registered its radio groups during build, or the group map was rebuilt while the item reference went stale.","triggerScenarios":"On Windows, calling MenuItem.SetChecked(true) on a NewMenuItemRadio item before the containing popup/context menu has been shown (radioGroups not yet populated), or after the menu was rebuilt so the *MenuItem in the map no longer equals the item being updated (pointer identity comparison fails).","commonSituations":"Toggling radio items from bindings right after startup; updating radio state from a background goroutine while the context menu is being rebuilt; reusing MenuItem pointers across menu rebuilds.","solutions":["Only SetChecked(true) on radio items after the popup/context menu has been opened at least once, or drive checked state via NewMenuItemRadio(label, true) at construction","Re-create menu items rather than reusing stale pointers across menu rebuilds","If it reproduces with fresh pointers and a shown menu, file a bug at wailsapp/wails with a minimal repro (popup menu + radio group)"],"exampleFix":"// before (panics if menu not yet shown / stale pointer)\nmyRadioItem.SetChecked(true)\n\n// after (set initial state at construction, update only after menu is shown)\nmyRadioItem := application.NewMenuItemRadio(\"Option A\", true)\n// later, after the context menu has been displayed:\nmyRadioItem.SetChecked(true)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"func safeSetChecked(item *application.MenuItem, checked bool) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tlog.Printf(\"SetChecked on radio item before menu registration: %v\", r)\n\t\t}\n\t}()\n\titem.SetChecked(checked)\n}","preventionTips":["Set initial radio state via NewMenuItemRadio(label, true) instead of post-hoc SetChecked","Do not call SetChecked on radio items before the popup menu has been shown at least once on Windows","Never cache MenuItem pointers across menu rebuilds; recreate items with the menu"],"tags":["windows","win32","menu","radio","popup","panic","state-management"],"backgroundTag":null,"analyzedSha":"0e754b1b40ba9044c2a1460e23b7c3de20fc5cf3","analyzedAt":"2026-08-15T14:17:36.034Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}