wailsapp/wails · error
no focused element to type into; pass a selector or click a
Error message
no focused element to type into; pass a selector or click a field first
What it means
CoInitializeEx initializes COM on a thread; E_UNEXPECTED indicates a generic, unforeseeable failure inside the COM runtime for that thread. The w32 wrapper panics with 'CoInitializeEx failed with E_UNEXPECTED'. Unlike the argument and memory cases, this HRESULT from CoInitializeEx usually means the thread's COM state is corrupted — e.g. mixed runtime versions, DLLs unloaded out of order, or a prior CoUninitialize imbalance on the same thread.
Source
Thrown at v3/pkg/application/mcp_inject.js:637
function shiftFocus(forward) {
const focusables = Array.from(document.querySelectorAll(
'a[href], button, input, textarea, select, [tabindex]:not([tabindex="-1"])',
)).filter((el) => !el.disabled && el.offsetParent !== null);
if (focusables.length === 0) return;
const index = focusables.indexOf(document.activeElement);
const next = forward
? focusables[(index + 1) % focusables.length]
: focusables[(index - 1 + focusables.length) % focusables.length];
next.focus();
}
async function typeText(text, selector, delay) {
if (selector) {
await click({ selector: selector });
}
let el = document.activeElement;
if (!el || el === document.body) {
throw new Error('no focused element to type into; pass a selector or click a field first');
}
const pause = typeof delay === 'number' && delay >= 0 ? delay : 25;
for (const ch of text) {
const key = ch === '\n' ? 'Enter' : ch;
await pressKey(el, key, {});
if (pause > 0) await sleep(pause);
el = document.activeElement || el;
}
const editable = editableHost(el);
if (editable) editable.dispatchEvent(new Event('change', { bubbles: true }));
return describe(el);
}
async function press(key, modifiers) {
const el = document.activeElement || document.body;
await pressKey(el, key, modifierInit(modifiers));
return describe(document.activeElement || el);
}View on GitHub (pinned to 0e754b1b40)
Solutions
- Audit CoInitializeEx/CoUninitialize pairing per thread: every successful init (including S_FALSE returns) needs exactly one CoUninitialize.
- Do not FreeLibrary DLLs that registered COM objects on threads that still use COM.
- Recreate the thread (goroutine on a fresh OS thread with LockOSThread) rather than re-initializing COM on a corrupted one.
- Move COM usage onto one dedicated, long-lived thread that initializes once at start.
Example fix
// before // cleanup path somewhere: CoUninitialize() called twice CoInitializeEx(COINIT_APARTMENTTHREADED) // later init -> E_UNEXPECTED // after // ensure strict pairing: init once per thread, uninit once runtime.LockOSThread() defer runtime.UnlockOSThread() hr := CoInitializeEx(COINIT_APARTMENTTHREADED) defer CoUninitialize()
Defensive patterns
Strategy: try-catch
Try / catch
defer func() {
if r := recover(); r != nil {
if msg, _ := r.(string); strings.Contains(msg, "E_UNEXPECTED") {
err = fmt.Errorf("com thread state corrupted; recreate thread")
return
}
panic(r)
}
}()
hr := CoInitializeEx(flags) Prevention
- Keep strict CoInitializeEx/CoUninitialize pairing per thread.
- Lock each COM-using goroutine to its OS thread.
- Do not unload DLLs that registered COM objects on live threads.
When it happens
Trigger: Calling CoInitializeEx on a thread where an earlier CoInitialize/CoUninitialize sequence was unbalanced (extra CoUninitialize dropped the thread below a clean state); unloading a DLL (FreeLibrary) that had registered COM class objects on that thread; nested COM usage from a plugin loaded and unloaded repeatedly.
Common situations: Plugin systems that LoadLibrary COM-registering DLLs and free them while the host thread still uses COM; long-lived threads that re-initialize COM after teardown with an unmatched CoUninitialize somewhere in cleanup.
Related errors
- element has zero size (is it hidden?): ' + target.selector
- Error occurred in App.Init
- SendMessage(LVM_UPDATE)
- ${await response.text()}
- target requires a selector or x/y coordinates
AI-assisted analysis of wailsapp/wails@0e754b1b40 (2026-08-15).
Data as JSON: /api/errors/d6ad997eb349ee0e.
Report an issue: GitHub.