grafana/k6 · error

focusing on element

Error message

focusing on element: %w

What it means

ElementHandle.focus() wraps the failure of a focus action that evaluates injected.focusNode on the element via CDP with no actionability preconditions. The wrapped error is usually a JavaScript evaluation failure (detached handle or destroyed execution context), a DOM error string returned by the injected script, or a timeout.

Solutions

  1. Re-acquire the element handle right before focusing it
  2. Wait for the page/frame to be ready: page.waitForLoadState() before the action
  3. Verify the element is still attached: await el.evaluate(e => e.isConnected)
  4. Raise K6_BROWSER_TIMEOUT if the session is just slow

Example fix

// before
const el = await page.$('#search');
await page.goto('https://app.example.com');
await el.focus(); // handle from previous page is dead

// after
await page.goto('https://app.example.com');
const el = await page.$('#search');
await el.focus();
Defensive patterns

Strategy: try-catch

Validate before calling

// Only focus elements confirmed to still be in the DOM
const connected = await el.evaluate((e) => e.isConnected).catch(() => false);
if (!connected) throw new Error('handle is stale; re-query before focus()');
await el.focus();

Try / catch

try {
  await el.focus();
} catch (e) {
  if (/Could not find object|Execution context|timed out/i.test(String(e.message))) {
    const fresh = await page.$(sel); // one re-query retry
    await fresh.focus();
  } else throw e;
}

Prevention

When it happens

Trigger: The element handle was detached by navigation or an SPA re-render so Runtime.callFunctionOn fails; the page navigates during the call destroying the execution context; the element sits in a frame that was closed; the default timeout (30s) expires on a stalled session.

Common situations: Focusing fields in SPAs right after route changes; handles stored in variables across page.goto() calls; interacting with elements in popups/iframes that the page closed.

Related errors


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

Appendix: 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 3fcf5388d7)