wailsapp/wails · error

Invoke GetIDsOfName error.

Error message

Invoke GetIDsOfName error.

What it means

ComGetIDsOfName invokes IDispatch::GetIDsOfNames and panics when the HRESULT is non-zero. This call maps method/property names to DISPIDs; failure usually means DISP_E_UNKNOWNNAME (the object has no member with that name) or a malformed/nil IDispatch pointer. The wrapper discards the per-name DISPIDs array that would normally reveal which name failed.

Source

Thrown at v3/pkg/w32/utils.go:120

	}
	return disp
}

func ComGetIDsOfName(disp *IDispatch, names []string) []int32 {
	wnames := make([]*uint16, len(names))
	dispid := make([]int32, len(names))
	for i := 0; i < len(names); i++ {
		wnames[i] = syscall.StringToUTF16Ptr(names[i])
	}
	hr, _, _ := syscall.SyscallN(disp.lpVtbl.pGetIDsOfNames,
		uintptr(unsafe.Pointer(disp)),
		uintptr(unsafe.Pointer(IID_NULL)),
		uintptr(unsafe.Pointer(&wnames[0])),
		uintptr(len(names)),
		uintptr(GetUserDefaultLCID()),
		uintptr(unsafe.Pointer(&dispid[0])))
	if hr != 0 {
		panic("Invoke GetIDsOfName error.")
	}
	return dispid
}

func ComInvoke(disp *IDispatch, dispid int32, dispatch int16, params ...interface{}) (result *VARIANT) {
	var dispparams DISPPARAMS

	if dispatch&DISPATCH_PROPERTYPUT != 0 {
		dispnames := [1]int32{DISPID_PROPERTYPUT}
		dispparams.RgdispidNamedArgs = uintptr(unsafe.Pointer(&dispnames[0]))
		dispparams.CNamedArgs = 1
	}
	var vargs []VARIANT
	if len(params) > 0 {
		vargs = make([]VARIANT, len(params))
		for i, v := range params {
			//n := len(params)-i-1
			n := len(params) - i - 1

View on GitHub (pinned to 0e754b1b40)

Solutions

  1. Verify the member name spelling and case against the object's type library / documentation (e.g. check in VBScript or PowerShell first)
  2. Confirm disp is a live IDispatch obtained from a successful CreateInstance/QueryInterface
  3. Resolve names one at a time to identify exactly which name fails
  4. Recover and report the failed names instead of crashing

Example fix

// before
ids := w32.ComGetIDsOfName(disp, []string{"Value", "TypoedName"}) // panics

// after
for _, name := range names {
    id, err := func(n string) (int32, error) {
        defer func() { _ = recover() }()
        return w32.ComGetIDsOfName(disp, []string{n})[0], nil
    }(name)
    if err != nil { return fmt.Errorf("unknown member %q", name) }
    _ = id
}
Defensive patterns

Strategy: validation

Validate before calling

if disp == nil || disp.LpVtbl == nil {
    return nil, errors.New("ComGetIDsOfName: nil IDispatch")
}
for _, n := range names {
    if n == "" { return nil, errors.New("empty member name") }
}

Try / catch

defer func() {
    if r := recover(); r != nil {
        err = fmt.Errorf("GetIDsOfNames failed for %v (check spelling/case): %v", names, r)
    }
}()

Prevention

When it happens

Trigger: Calling ComInvoke/ComGetIDsOfName with a misspelled member name (case-sensitive against the object's typeinfo); names localized on a different locale; disp being nil or from a released object; passing more names than the object supports resolving at once.

Common situations: Scripting COM automation (Office, WScript.Shell, shell objects) from Go where the method name changed between object versions or was guessed; typos in property names; calling late-bound members on objects that only expose a restricted dispatch interface.

Related errors


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