{"record":{"id":"5ff5c953d1713c8f","repo":"wailsapp/wails","slug":"unkown-type","errorCode":null,"errorMessage":"unkown type","messagePattern":"unkown type","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/pkg/w32/user32.go","lineNumber":1435,"sourceCode":"\treturn int32(ret)\n}\n\n/*\nfunc SendInput(inputs []INPUT) uint32 {\n\tvar validInputs []C.INPUT\n\n\tfor _, oneInput := range inputs {\n\t\tinput := C.INPUT{_type: C.DWORD(oneInput.Type)}\n\n\t\tswitch oneInput.Type {\n\t\tcase INPUT_MOUSE:\n\t\t\t(*MouseInput)(unsafe.Pointer(&input)).mi = oneInput.Mi\n\t\tcase INPUT_KEYBOARD:\n\t\t\t(*KbdInput)(unsafe.Pointer(&input)).ki = oneInput.Ki\n\t\tcase INPUT_HARDWARE:\n\t\t\t(*HardwareInput)(unsafe.Pointer(&input)).hi = oneInput.Hi\n\t\tdefault:\n\t\t\tpanic(\"unkown type\")\n\t\t}\n\n\t\tvalidInputs = append(validInputs, input)\n\t}\n\n\tret, _, _ := procSendInput.Call(\n\t\tuintptr(len(validInputs)),\n\t\tuintptr(unsafe.Pointer(&validInputs[0])),\n\t\tuintptr(unsafe.Sizeof(C.INPUT{})),\n\t)\n\treturn uint32(ret)\n}*/\n\nfunc SetWindowsHookEx(idHook int, lpfn HOOKPROC, hMod HINSTANCE, dwThreadId DWORD) HHOOK {\n\tret, _, _ := procSetWindowsHookEx.Call(\n\t\tuintptr(idHook),\n\t\tuintptr(syscall.NewCallback(lpfn)),\n\t\tuintptr(hMod),","sourceCodeStart":1417,"sourceCodeEnd":1453,"githubUrl":"https://github.com/wailsapp/wails/blob/0e754b1b40ba9044c2a1460e23b7c3de20fc5cf3/v3/pkg/w32/user32.go#L1417-L1453","documentation":"The SendInput wrapper panics with 'unkown type' (sic) when an element of the inputs slice has a Type that is not INPUT_MOUSE, INPUT_KEYBOARD, or INPUT_HARDWARE. SendInput serializes a heterogeneous INPUT array; each element must tag which union member (mi/ki/hi) is populated, and the wrapper refuses untagged or corrupted values.","triggerScenarios":"Building INPUT structs with Type left at the zero value (0 is not a valid input type — mouse is 0, keyboard 1, hardware 2 in the raw API, but the wrapper requires the named constants exactly); passing a struct literal that omits the Type field; bit flags ORed into Type.","commonSituations":"Synthetic input / automation code (simulated keystrokes for global shortcuts, test harnesses) where the Type field is forgotten in a struct literal; values coming from user config parsed as raw ints that do not match the constants.","solutions":["Always set Type explicitly: w32.KeyboardInput uses {Type: w32.INPUT_KEYBOARD, Ki: ...}","Map raw config integers to the three constants before building the slice","Validate the slice in a loop before calling SendInput and reject/log unknown types instead of panicking"],"exampleFix":"// before\ninputs := []w32.Input{{Ki: w32.KbdInput{...}}} // Type omitted -> panic\nw32.SendInput(inputs)\n\n// after\ninputs := []w32.Input{{Type: w32.INPUT_KEYBOARD, Ki: w32.KbdInput{...}}}\nw32.SendInput(inputs)","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func isValidInputType(t uint32) bool {\n    return t == w32.INPUT_MOUSE || t == w32.INPUT_KEYBOARD || t == w32.INPUT_HARDWARE\n}","tryCatchPattern":null,"preventionTips":["Always set the Type field in INPUT literals","Validate config-driven input values against the three constants before building the slice"],"tags":["windows","win32","sendinput","validation","panic"],"backgroundTag":null,"analyzedSha":"0e754b1b40ba9044c2a1460e23b7c3de20fc5cf3","analyzedAt":"2026-08-15T14:17:36.034Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}