wailsapp/wails · error
failed CreateMenu
Error message
failed CreateMenu
What it means
Form.NewMenu calls the Win32 CreateMenu to allocate a menu bar and panics when it returns NULL. CreateMenu fails essentially only when the process is out of kernel handle-table slots or heap for menu objects — there are no caller-controllable arguments. In practice this panic indicates severe resource pressure (handle leak) or creation after window/thread teardown has begun.
Source
Thrown at v2/internal/frontend/desktop/windows/winc/form.go:104
fm.SetText("Form")
return fm
}
func (fm *Form) SetLayout(mng LayoutManager) {
fm.layoutMng = mng
}
// UpdateLayout refresh layout.
func (fm *Form) UpdateLayout() {
if fm.layoutMng != nil {
fm.layoutMng.Update()
}
}
func (fm *Form) NewMenu() *Menu {
hMenu := w32.CreateMenu()
if hMenu == 0 {
panic("failed CreateMenu")
}
m := &Menu{hMenu: hMenu, hwnd: fm.hwnd}
if !w32.SetMenu(fm.hwnd, hMenu) {
panic("failed SetMenu")
}
return m
}
func (fm *Form) DisableIcon() {
windowInfo := getWindowInfo(fm.hwnd)
frameless := windowInfo.IsPopup()
if frameless {
return
}
exStyle := w32.GetWindowLong(fm.hwnd, w32.GWL_EXSTYLE)
w32.SetWindowLong(fm.hwnd, w32.GWL_EXSTYLE, uint32(exStyle|w32.WS_EX_DLGMODALFRAME))
w32.SetWindowPos(fm.hwnd, 0, 0, 0, 0, 0,
uint(View on GitHub (pinned to 0e754b1b40)
Solutions
- Create the menu once per Form and mutate it (AppendItem/Remove) instead of calling NewMenu repeatedly
- Destroy replaced menus with w32.DestroyMenu(hMenu)
- Track handle count (Task Manager -> Details -> Handles); if it grows unbounded, find and fix the leak — the menu is the victim
Example fix
// before
func (f *MainForm) refreshMenu(items []Item) {
m := f.NewMenu() // new HMENU every refresh, old one leaked
for _, it := range items { m.AppendItem(...) }
}
// after
// create once in setup: f.menu = f.NewMenu()
func (f *MainForm) refreshMenu(items []Item) {
for f.menu.Count() > 0 { f.menu.Remove(0) } // mutate the existing menu
for _, it := range items { f.menu.AppendItem(...) }
} Defensive patterns
Strategy: validation
Validate before calling
// Create the menu once; guard against resource exhaustion before extra menus.
if w32.GetGuiResources(w32.GetCurrentProcess(), 1 /*GR_USEROBJECTS+handles*/) < 9000 {
m := form.NewMenu()
} Prevention
- One menu per form; mutate it instead of recreating
- DestroyMenu any replaced HMENU
- Track process handle counts to catch leaks
When it happens
Trigger: Calling form.NewMenu() repeatedly without DestroyMenu on replaced menus, leaking menu handles; calling NewMenu during process shutdown; a broader HANDLE leak (files, GDI, events) exhausting the kernel handle quota.
Common situations: Apps that rebuild menus dynamically (e.g. per locale switch or per window state) and never destroy the old HMENU; long-running Wails v2 utilities with unbounded handle growth.
Related errors
- failed SetMenu
- Faild to create solid color brush
- GetSysColorBrush failed
- Failed to create null brush
- Create canvas from %v failed.
AI-assisted analysis of wailsapp/wails@0e754b1b40 (2026-08-15).
Data as JSON: /api/errors/3bb67e0c6cea768f.
Report an issue: GitHub.