wailsapp/wails · error
unknown type
Error message
unknown type
What it means
ComInvoke converts variadic params into VARIANTs with a type switch covering int/int32, uint/uint32, int64, uint64, float32/64 (and pointers to each), string, *string, *IDispatch, **IDispatch, nil, and *VARIANT; anything else hits the default case and panics with 'unknown type'. It is a Marshaling limitation of this minimal wrapper, not a COM failure.
Source
Thrown at v3/pkg/w32/utils.go:198
vargs[n] = VARIANT{VT_R4 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*float32))))}
case float64:
vargs[n] = VARIANT{VT_R8, 0, 0, 0, int64(v.(float64))}
case *float64:
vargs[n] = VARIANT{VT_R8 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*float64))))}
case string:
vargs[n] = VARIANT{VT_BSTR, 0, 0, 0, int64(uintptr(unsafe.Pointer(SysAllocString(v.(string)))))}
case *string:
vargs[n] = VARIANT{VT_BSTR | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*string))))}
case *IDispatch:
vargs[n] = VARIANT{VT_DISPATCH, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*IDispatch))))}
case **IDispatch:
vargs[n] = VARIANT{VT_DISPATCH | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(**IDispatch))))}
case nil:
vargs[n] = VARIANT{VT_NULL, 0, 0, 0, 0}
case *VARIANT:
vargs[n] = VARIANT{VT_VARIANT | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*VARIANT))))}
default:
panic("unknown type")
}
}
dispparams.Rgvarg = uintptr(unsafe.Pointer(&vargs[0]))
dispparams.CArgs = uint32(len(params))
}
var ret VARIANT
var excepInfo EXCEPINFO
VariantInit(&ret)
hr, _, _ := syscall.SyscallN(disp.lpVtbl.pInvoke,
uintptr(unsafe.Pointer(disp)),
uintptr(dispid),
uintptr(unsafe.Pointer(IID_NULL)),
uintptr(GetUserDefaultLCID()),
uintptr(dispatch),
uintptr(unsafe.Pointer(&dispparams)),
uintptr(unsafe.Pointer(&ret)),
uintptr(unsafe.Pointer(&excepInfo)),View on GitHub (pinned to 0e754b1b40)
Solutions
- Convert bools before the call — e.g. pass int32(-1)/int32(0) for VARIANT_TRUE/FALSE, or add a bool case mapping to VT_BOOL in the wrapper
- Narrow custom typed ints/floats to the built-in types (int32(weekDay), float64(ratio)) before calling
- For complex values, build a *w32.VARIANT yourself and pass that (VT_VARIANT|VT_BYREF is supported)
- Extend the switch upstream with the missing cases and contribute the patch
Example fix
// before w32.ComInvoke(disp, dispid, w32.DISPATCH_METHOD, true) // bool -> panic // after variantTrue := int32(-1) // VARIANT_TRUE w32.ComInvoke(disp, dispid, w32.DISPATCH_METHOD, variantTrue)
Defensive patterns
Strategy: type-guard
Type guard
func isSupportedVariantParam(v any) bool {
switch v.(type) {
case int, int32, uint, uint32, int64, uint64,
float32, float64, string, *string,
*w32.IDispatch, **w32.IDispatch, *w32.VARIANT, nil:
return true
case int8, uint8, int16, uint16, bool, []byte, time.Time:
return false
}
return false
} Prevention
- Convert bools to int32(-1)/int32(0) and narrow custom numeric types before ComInvoke
- Pre-convert complex values into a *w32.VARIANT yourself
- Add a unit test that runs isSupportedVariantParam over every param you pass
When it happens
Trigger: Passing bool, int8/uint8, int16/uint16 (non-pointer), []byte, time.Time, structs, or any custom type as a parameter to w32.ComInvoke/ComPutProperty; passing a nil-valued interface with a concrete non-nil type.
Common situations: Automating COM APIs whose documented parameters are booleans (VT_BOOL) — the wrapper has no bool case, so even correct-looking code panics; passing Go strings wrapped in custom string types; sending enums represented as custom int types.
Related errors
- Invoke VariantInit error.
- element has zero size (is it hidden?): ' + target.selector
- target requires a selector or x/y coordinates
- no focused element to type into; pass a selector or click a
- no element matches selector: ' + selector
AI-assisted analysis of wailsapp/wails@0e754b1b40 (2026-08-15).
Data as JSON: /api/errors/0da839cd7ffae17e.
Report an issue: GitHub.