wailsapp/wails · error
missing icon with icon ID: %d
Error message
missing icon with icon ID: %d
What it means
Button.SetResIcon tries to load an icon by numeric resource ID from the executable's resources via NewIconFromResource(GetAppInstance(), iconID); if the lookup fails it panics with the missing ID. This means the .exe (or the module returned by GetAppInstance) has no icon resource with that numeric ID — common when resources live in a linked .syso/.rc file that was not built in, or the ID was taken from a header that does not match the compiled resource script.
Source
Thrown at v2/internal/frontend/desktop/windows/winc/buttons.go:63
func (bt *Button) SetChecked(checked bool) {
wparam := w32.BST_CHECKED
if !checked {
wparam = w32.BST_UNCHECKED
}
w32.SendMessage(bt.hwnd, w32.BM_SETCHECK, uintptr(wparam), 0)
}
// SetIcon sets icon on the button. Recommended icons are 32x32 with 32bit color depth.
func (bt *Button) SetIcon(ico *Icon) {
w32.SendMessage(bt.hwnd, w32.BM_SETIMAGE, w32.IMAGE_ICON, uintptr(ico.handle))
}
func (bt *Button) SetResIcon(iconID uint16) {
if ico, err := NewIconFromResource(GetAppInstance(), iconID); err == nil {
bt.SetIcon(ico)
return
}
panic(fmt.Sprintf("missing icon with icon ID: %d", iconID))
}
type PushButton struct {
Button
}
func NewPushButton(parent Controller) *PushButton {
pb := new(PushButton)
pb.InitControl("BUTTON", parent, 0, w32.BS_PUSHBUTTON|w32.WS_TABSTOP|w32.WS_VISIBLE|w32.WS_CHILD)
RegMsgHandler(pb)
pb.SetFont(DefaultFont)
pb.SetText("Button")
pb.SetSize(100, 22)
return pb
}View on GitHub (pinned to 0e754b1b40)
Solutions
- Inspect the built executable's resources (Resource Hacker, or `windres`/`go-winres` dump) and confirm an icon exists with the exact numeric ID passed to SetResIcon
- Keep resource IDs in a single shared resource.h and regenerate the .syso whenever IDs change: `go-winres simply --icon-id=<id>` (or windres) then rebuild
- Load icons by file path or embedded bytes instead (NewIconFromResource is module-based): use image.NewIconFromFile / embed the icon and create it from an HICON you control
- Guard with a runtime lookup before calling SetResIcon (see validation code) so a missing icon degrades gracefully instead of panicking
Example fix
// before
btn.SetResIcon(101) // panics if exe has no icon resource 101
// after
if _, err := winc.NewIconFromResource(winc.GetAppInstance(), 101); err == nil {
btn.SetResIcon(101)
} else {
ico, _ := winc.NewIconFromFile("assets/button.ico")
if ico != nil { btn.SetIcon(ico) }
} Defensive patterns
Strategy: validation
Validate before calling
func resIconExists(id uint16) bool {
_, err := winc.NewIconFromResource(winc.GetAppInstance(), id)
return err == nil
}
if resIconExists(101) {
btn.SetResIcon(101)
} else {
if ico, err := winc.NewIconFromFile("assets/fallback.ico"); err == nil {
btn.SetIcon(ico)
}
} Prevention
- Keep resource IDs in one generated header; regenerate the .syso whenever icons change
- Verify embedded icons in CI by dumping resources from the built exe
- Prefer SetIcon with a loaded Icon over SetResIcon for app-owned assets
When it happens
Trigger: Calling button.SetResIcon(n) where n is not defined as an ICON resource in the application's .rc/.syso; IDs shifted because the .rc auto-numbering (or a resource header like resource.h) changed; the resource was embedded as a string name instead of a numeric ID.
Common situations: Wails v2 Windows apps embedding icons via windres/go-winres .syso files where the generated IDs don't match; porting WinForms-style code that used MAKEINTRESOURCE IDs from a different project; CI builds stripping resources.
Related errors
- missing icon with icon ID: %d
- IconType is invalid
- invalid stream batch acknowledgement
- no element matches selector: ' + target.selector
- Faild to create solid color brush
AI-assisted analysis of wailsapp/wails@0e754b1b40 (2026-08-15).
Data as JSON: /api/errors/9663f9d6dc154607.
Report an issue: GitHub.