grafana/k6 · error

checking hit target

Error message

checking hit target: %w

What it means

Final actionability stage of the k6 browser module's pointer-action pipeline (unless opts.Force): checkHitTargetAt evaluates the injected script at the computed point to verify the element (or a descendant) would actually receive the pointer event, recursing through iframes. When the check reports failure, the dominant cause is error:intercept — 'another element is intercepting pointer action' — i.e., a different node sits on top at that point; evaluation/context failures also surface here.

Solutions

  1. Dismiss the overlay first: click the consent/close button or wait for the overlay to detach: page.waitForSelector('.overlay', { state: 'detached' }).
  2. Click a different spot of the element with { position: { x, y } } away from the covering child/overlay.
  3. If interception is expected and acceptable, pass { force: true } to skip hit-target verification.
  4. Ensure animations on overlays complete (wait for opacity/visibility transitions) before acting.

Example fix

// before
const el = await page.$('#accept-terms');
await el.click(); // cookie banner covers the button

// after
await page.click('#cookie-consent-accept', { timeout: '5s' }).catch(() => {});
await page.waitForSelector('.cookie-banner', { state: 'detached', timeout: '10s' }).catch(() => {});
const el = await page.waitForSelector('#accept-terms', { state: 'visible' });
await el.click();
Defensive patterns

Strategy: try-catch

Validate before calling

// proactively remove known overlays before pointer actions
await page.click('#cookie-consent-accept', { timeout: '3s' }).catch(() => {});
await page.waitForSelector('.cookie-banner', { state: 'detached', timeout: '5s' }).catch(() => {});
await el.click();

Try / catch

try {
  await el.click({ timeout: '30s' });
} catch (e) {
  if (String(e).includes('intercept') || String(e).includes('checking hit target')) {
    await el.click({ position: { x: 5, y: 5 } }); // try uncovered spot
  } else { throw e; }
}

Prevention

When it happens

Trigger: click()/tap() when a cookie banner, modal backdrop, sticky header, spinner overlay, or chat widget covers the element; the element's center covered by its own child label/badge; hit-target evaluation failing because the frame navigated or the execution context was destroyed.

Common situations: Cookie-consent and GDPR banners on first visit; full-page loading overlays not fully faded (opacity animations) while checks pass 'visible/stable'; sticky navbars covering scrolled-to targets; elements whose clickable center falls on a covering pseudo-element.

Related errors


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

Appendix: source

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

		} else {
			p, err = h.clickablePoint()
			if err != nil {
				return nil, fmt.Errorf("pointer action: %w", err)
			}
		}

		// Further translation of the point might be necessary if the point
		// is still relative to the parent frame it is in and not the page.
		*p, err = h.translatePointToPage(apiCtx, *p)
		if err != nil {
			return nil, fmt.Errorf("translating point to page: %w", err)
		}

		// Do a final actionability check to see if element can receive events
		// at mouse position in question
		if !opts.Force {
			if ok, err := h.checkHitTargetAt(apiCtx, *p); !ok {
				return nil, fmt.Errorf("checking hit target: %w", err)
			}
		}
		// Are we only "trialing" the action but not actually performing
		// it (ie. running the actionability checks).
		if opts.Trial {
			return nil, nil //nolint:nilnil
		}

		b := NewBarrier()
		h.frame.manager.addBarrier(b)
		defer h.frame.manager.removeBarrier(b)
		if res, err = fn(apiCtx, h, p); err != nil {
			return nil, fmt.Errorf("evaluating pointer action: %w", err)
		}
		// Do we need to wait for navigation to happen
		if !opts.NoWaitAfter {
			if err = b.Wait(apiCtx); err != nil {
				return nil, fmt.Errorf("waiting for navigation: %w", err)

View on GitHub (pinned to 3fcf5388d7)