wailsapp/wails · error

missing icon with icon ID: %d

Error message

missing icon with icon ID: %d

What it means

ImageList.AddResIcon loads an icon by numeric resource ID from the executable via NewIconFromResource(GetAppInstance(), iconID) and panics when the load fails, mirroring Button.SetResIcon. The panic means the module returned by GetAppInstance has no icon resource with that numeric ID — the .syso/.rc resources baked into the binary don't contain it (or contain it under a different ID/name).

Source

Thrown at v2/internal/frontend/desktop/windows/winc/imagelist.go:55

func (im *ImageList) SetImageCount(uNewCount uint) bool {
	return w32.ImageList_SetImageCount(im.handle, uNewCount)
}

func (im *ImageList) ImageCount() int {
	return w32.ImageList_GetImageCount(im.handle)
}

func (im *ImageList) AddIcon(icon *Icon) int {
	return w32.ImageList_AddIcon(im.handle, icon.Handle())
}

func (im *ImageList) AddResIcon(iconID uint16) {
	if ico, err := NewIconFromResource(GetAppInstance(), iconID); err == nil {
		im.AddIcon(ico)
		return
	}
	panic(fmt.Sprintf("missing icon with icon ID: %d", iconID))
}

func (im *ImageList) RemoveAll() bool {
	return w32.ImageList_RemoveAll(im.handle)
}

func (im *ImageList) Remove(i int) bool {
	return w32.ImageList_Remove(im.handle, i)
}

View on GitHub (pinned to 0e754b1b40)

Solutions

  1. Dump the exe's resources (Resource Hacker / go-winres) and align the numeric ID passed to AddResIcon with an actually embedded icon
  2. Centralize resource IDs in one generated header and regenerate the .syso whenever icons change
  3. Prefer loading icons you ship (NewIconFromFile / embedded bytes -> HICON) and use iml.AddIcon(ico) instead of resource IDs
  4. Validate availability first (see validation code) and degrade to a default icon rather than crashing

Example fix

// before
iml.AddResIcon(101) // panics when exe lacks icon resource 101

// after
if ico, err := winc.NewIconFromResource(winc.GetAppInstance(), 101); err == nil {
    iml.AddIcon(ico)
} else if d, err2 := winc.NewIconFromFile("assets/item.ico"); err2 == nil {
    iml.AddIcon(d)
}
Defensive patterns

Strategy: validation

Validate before calling

func addResIconSafe(iml *winc.ImageList, id uint16) bool {
    if ico, err := winc.NewIconFromResource(winc.GetAppInstance(), id); err == nil {
        iml.AddIcon(ico)
        return true
    }
    if d, err := winc.NewIconFromFile("assets/default.ico"); err == nil {
        iml.AddIcon(d)
    }
    return false
}

Prevention

When it happens

Trigger: Calling iml.AddResIcon(n) where n is absent from the exe's resources; resource IDs shifted after regenerating the .rc/.syso; icons embedded under string names rather than numeric IDs; adding the icon to an image list for a ListView/TreeView toolbar at startup.

Common situations: Wails v2 Windows builds using go-winres/windres .syso files whose icon IDs drift from constants in code; SVI/tree controls populated from shell32-style IDs that were never embedded in this exe.

Related errors


AI-assisted analysis of wailsapp/wails@0e754b1b40 (2026-08-15). Data as JSON: /api/errors/6d5b827e870054d8. Report an issue: GitHub.