grafana/k6 · error

focusing on element: %w

Error message

focusing on element: %w

What it means

Returned by ElementHandle.focus() when focusing the element fails. Unlike fill/click, focus registers no actionability preconditions (empty checks list), so the wrapped cause is almost never a visibility failure: it is a stale handle (remote object released), a destroyed execution context from navigation, or an expired timeout while the internal action retried. The %w chain holds the underlying CDP error.

Source

Thrown at internal/js/modules/k6/browser/common/element_handle.go:934

		return fmt.Errorf("filling element: %w", err)
	}

	applySlowMo(h.ctx)

	return nil
}

// Focus scrolls element into view and focuses the element.
func (h *ElementHandle) Focus() error {
	focus := func(apiCtx context.Context, handle *ElementHandle) (any, error) {
		return nil, handle.focus(apiCtx, false)
	}
	opts := NewElementHandleBaseOptions(h.DefaultTimeout())
	focusAction := h.newAction(
		[]string{}, focus, opts.Force, withRetry, opts.NoWaitAfter, opts.Timeout,
	)
	if _, err := call(h.ctx, focusAction, opts.Timeout); err != nil {
		return fmt.Errorf("focusing on element: %w", err)
	}

	applySlowMo(h.ctx)

	return nil
}

// GetAttribute retrieves the value of specified element attribute.
// The second return value is true if the attribute exists, and false otherwise.
func (h *ElementHandle) GetAttribute(name string) (string, bool, error) {
	getAttribute := func(apiCtx context.Context, handle *ElementHandle) (any, error) {
		return handle.getAttribute(apiCtx, name)
	}
	opts := NewElementHandleBaseOptions(h.DefaultTimeout())
	getAttributeAction := h.newAction(
		[]string{}, getAttribute, opts.Force, withRetry, opts.NoWaitAfter, opts.Timeout,
	)

View on GitHub (pinned to 93accf6570)

Solutions

  1. Re-query the element handle immediately before focus() so it cannot be stale
  2. Wait for the element first: page.waitForSelector(sel, { state: 'attached' })
  3. Sequence navigations with page.waitForNavigation()/waitForLoadState() so focus runs in a stable context
  4. Raise the timeout via the browser 'timeout' option if the app is slow to settle

Example fix

// before
const h = await page.$('#search');
await page.goto('https://example.com/next');
await h.focus(); // stale handle
// after
await page.goto('https://example.com/next');
await page.waitForSelector('#search');
const h = await page.$('#search');
await h.focus();
Defensive patterns

Strategy: try-catch

Validate before calling

await page.waitForSelector('#search', { state: 'attached' });
const h = await page.$('#search');
if (await h.isVisible()) {
  await h.focus();
}

Try / catch

try {
  await handle.focus();
} catch (e) {
  if (String(e).includes('focusing on element')) {
    const fresh = await page.$(sel);
    if (fresh) await fresh.focus();
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: handle.focus() on a handle obtained before a navigation or DOM re-render; the element was removed from the DOM; the execution context was destroyed mid-action by page.goto or a redirect; the page or browser was closed while focus was pending.

Common situations: Storing page.$() handles across await points in SPAs; focusing inside a loop after the page navigated between iterations; closing the browser context in an error branch while a focus is still in flight; slow pages where the default timeout is exceeded.

Related errors


AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15). Data as JSON: /api/errors/3392106af78fbebe. Report an issue: GitHub.