{"record":{"id":"d6ad997eb349ee0e","repo":"wailsapp/wails","slug":"no-focused-element-to-type-into-pass-a-selector-o","errorCode":null,"errorMessage":"no focused element to type into; pass a selector or click a field first","messagePattern":"no focused element to type into; pass a selector or click a field first","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/pkg/application/mcp_inject.js","lineNumber":637,"sourceCode":"    function shiftFocus(forward) {\n        const focusables = Array.from(document.querySelectorAll(\n            'a[href], button, input, textarea, select, [tabindex]:not([tabindex=\"-1\"])',\n        )).filter((el) => !el.disabled && el.offsetParent !== null);\n        if (focusables.length === 0) return;\n        const index = focusables.indexOf(document.activeElement);\n        const next = forward\n            ? focusables[(index + 1) % focusables.length]\n            : focusables[(index - 1 + focusables.length) % focusables.length];\n        next.focus();\n    }\n\n    async function typeText(text, selector, delay) {\n        if (selector) {\n            await click({ selector: selector });\n        }\n        let el = document.activeElement;\n        if (!el || el === document.body) {\n            throw new Error('no focused element to type into; pass a selector or click a field first');\n        }\n        const pause = typeof delay === 'number' && delay >= 0 ? delay : 25;\n        for (const ch of text) {\n            const key = ch === '\\n' ? 'Enter' : ch;\n            await pressKey(el, key, {});\n            if (pause > 0) await sleep(pause);\n            el = document.activeElement || el;\n        }\n        const editable = editableHost(el);\n        if (editable) editable.dispatchEvent(new Event('change', { bubbles: true }));\n        return describe(el);\n    }\n\n    async function press(key, modifiers) {\n        const el = document.activeElement || document.body;\n        await pressKey(el, key, modifierInit(modifiers));\n        return describe(document.activeElement || el);\n    }","sourceCodeStart":619,"sourceCodeEnd":655,"githubUrl":"https://github.com/wailsapp/wails/blob/0e754b1b40ba9044c2a1460e23b7c3de20fc5cf3/v3/pkg/application/mcp_inject.js#L619-L655","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n// cleanup path somewhere: CoUninitialize() called twice\nCoInitializeEx(COINIT_APARTMENTTHREADED) // later init -> E_UNEXPECTED\n\n// after\n// ensure strict pairing: init once per thread, uninit once\nruntime.LockOSThread()\ndefer runtime.UnlockOSThread()\nhr := CoInitializeEx(COINIT_APARTMENTTHREADED)\ndefer CoUninitialize()","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"defer func() {\n\tif r := recover(); r != nil {\n\t\tif msg, _ := r.(string); strings.Contains(msg, \"E_UNEXPECTED\") {\n\t\t\terr = fmt.Errorf(\"com thread state corrupted; recreate thread\")\n\t\t\treturn\n\t\t}\n\t\tpanic(r)\n\t}\n}()\nhr := CoInitializeEx(flags)","preventionTips":["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."],"tags":["windows","com","threading","lifecycle","panic"],"backgroundTag":null,"analyzedSha":"0e754b1b40ba9044c2a1460e23b7c3de20fc5cf3","analyzedAt":"2026-08-15T14:17:36.034Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}