wailsapp/wails · error

element has zero size (is it hidden?): ' + target.selector

Error message

element has zero size (is it hidden?): ' + target.selector

What it means

CoInitializeEx initializes COM on the current thread with a concurrency model (e.g. COINIT_APARTMENTTHREADED). The w32 wrapper panics with a distinct message per failure HRESULT; E_INVALIDARG means the dwCoInit flags passed are not a valid combination. Valid values are COINIT_APARTMENTTHREADED or COINIT_MULTITHREADED (mutually exclusive), optionally ORed with COINIT_DISABLE_OLE1DDE, COINIT_SPEED_OVER_MEMORY. Passing both apartment flags, an undefined bit, or a garbage uintptr triggers this.

Source

Thrown at v3/pkg/application/mcp_inject.js:294

            },
        };
        if ('value' in el && typeof el.value === 'string') description.value = el.value.slice(0, 500);
        if (el.disabled) description.disabled = true;
        if (el.href) description.href = el.href;
        return description;
    }

    // Resolve {selector} or {x, y} into concrete viewport coordinates,
    // scrolling selector targets into view first.
    async function resolveTarget(target) {
        if (target && target.selector) {
            const el = document.querySelector(target.selector);
            if (!el) throw new Error('no element matches selector: ' + target.selector);
            el.scrollIntoView({ block: 'center', inline: 'center', behavior: 'instant' });
            await nextFrame();
            const rect = el.getBoundingClientRect();
            if (rect.width === 0 && rect.height === 0) {
                throw new Error('element has zero size (is it hidden?): ' + target.selector);
            }
            const point = clampToViewport(rect.x + rect.width / 2, rect.y + rect.height / 2);
            return { x: Math.round(point.x), y: Math.round(point.y), el };
        }
        if (target && typeof target.x === 'number' && typeof target.y === 'number') {
            const point = clampToViewport(target.x, target.y);
            return { x: Math.round(point.x), y: Math.round(point.y), el: null };
        }
        throw new Error('target requires a selector or x/y coordinates');
    }

    const BUTTONS = { left: 0, middle: 1, right: 2 };
    const BUTTON_MASKS = { 0: 1, 1: 4, 2: 2 };

    function focusTarget(el) {
        const focusable = el && el.closest
            ? el.closest('input, textarea, select, button, a[href], [tabindex], [contenteditable]')
            : null;

View on GitHub (pinned to 0e754b1b40)

Solutions

  1. Pass exactly one apartment model flag, e.g. w32.COINIT_APARTMENTTHREADED, using constants from the same w32 package.
  2. If flags come from config, validate them against the known set before calling.
  3. Check for accidental OR of both apartment flags in code that 'falls back' between models — COM requires picking one per thread.
  4. Compare against a known-good call such as the one in v3/pkg/w32/taskbar.go which uses COINIT_APARTMENTTHREADED.

Example fix

// before
coinit := COINIT_APARTMENTTHREADED | COINIT_MULTITHREADED // invalid combo -> panic
CoInitializeEx(uintptr(coinit))

// after
CoInitializeEx(COINIT_APARTMENTTHREADED)
Defensive patterns

Strategy: validation

Validate before calling

func validCoInitFlags(f uintptr) bool {
	apartment := f & (w32.COINIT_APARTMENTTHREADED | w32.COINIT_MULTITHREADED)
	if apartment != w32.COINIT_APARTMENTTHREADED && apartment != w32.COINIT_MULTITHREADED {
		return false
	}
	return f & ^(w32.COINIT_APARTMENTTHREADED|w32.COINIT_MULTITHREADED|
		w32.COINIT_DISABLE_OLE1DDE|w32.COINIT_SPEED_OVER_MEMORY) == 0
}

Prevention

When it happens

Trigger: Passing COINIT_APARTMENTTHREADED|COINIT_MULTITHREADED together; computing flags dynamically and including bits not in the legal set; porting code that used a stale constant value from another package with different numbering.

Common situations: Mixing COM flag constants from different Go Windows packages (e.g. golang.org/x/sys/windows vs a vendored copy) where numeric values or extra bits differ; a typo'd hex literal in hand-written flags.

Related errors


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