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
- Dismiss the overlay first: click the consent/close button or wait for the overlay to detach: page.waitForSelector('.overlay', { state: 'detached' }).
- Click a different spot of the element with { position: { x, y } } away from the covering child/overlay.
- If interception is expected and acceptable, pass { force: true } to skip hit-target verification.
- 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
- Standardize a consent-banner dismissal step at the start of every page flow.
- Wait for fading overlays to fully detach, not just become transparent, before clicking.
- Reserve force:true for cases where interception is understood and acceptable.
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
- getting element position
- pointer action
- translating point to page
- waiting for element state
- getting injected script
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)