microsoft/playwright · error · NonRecoverableDOMError

${result.hitTargetDescription} intercepts pointer events

Error message

${result.hitTargetDescription} intercepts pointer events

What it means

The action returned an object with a `hitTargetDescription`, meaning another element is covering the target at the click point and intercepting pointer events (elementFromPoint returns a different node). With force:true or noAutoWaiting the loop cannot wait for the overlay to disappear, so it throws NonRecoverableDOMError including a description of the intercepting element.

Source

Thrown at packages/playwright-core/src/server/dom.ts:366

          throw new NonRecoverableDOMError('Element is outside of the viewport');
        progress.log('  element is outside of the viewport');
        continue;
      }
      if (result === 'error:optionsnotfound') {
        if (noAutoWaiting)
          throw new NonRecoverableDOMError('Did not find some options');
        progress.log('  did not find some options');
        continue;
      }
      if (result === 'error:optionnotenabled') {
        if (noAutoWaiting)
          throw new NonRecoverableDOMError('Option being selected is not enabled');
        progress.log('  option being selected is not enabled');
        continue;
      }
      if (typeof result === 'object' && 'hitTargetDescription' in result) {
        if (noAutoWaiting)
          throw new NonRecoverableDOMError(`${result.hitTargetDescription} intercepts pointer events`);
        progress.log(`  ${result.hitTargetDescription} intercepts pointer events`);
        continue;
      }
      if (typeof result === 'object' && 'missingState' in result) {
        if (noAutoWaiting)
          throw new NonRecoverableDOMError(`Element is not ${result.missingState}`);
        progress.log(`  element is not ${result.missingState}`);
        continue;
      }
      return result;
    }
  }

  async _retryPointerAction(progress: Progress, actionName: ActionName, waitForEnabled: boolean, action: (progress: Progress, point: types.Point) => Promise<void>,
    options: { waitAfter: boolean | 'disabled' } & types.PointerActionOptions & types.PointerActionWaitOptions): Promise<'error:notconnected' | 'done'> {
    // Note: do not perform locator handlers checkpoint to avoid moving the mouse in the middle of a drag operation.
    const skipActionPreChecks = actionName === 'move and up';
    return await this._retryAction(progress, actionName, async (progress, retry) => {

View on GitHub (pinned to c8fc3bf8d3)

Solutions

  1. Remove force:true so Playwright waits for the intercepting element to disappear.
  2. Dismiss the overlay first (click the cookie-banner accept, wait for the loader to hide).
  3. Use a click position that is not covered, or scroll so the target is clear of the overlay.
  4. Check the error's hitTargetDescription to identify what is intercepting.

Example fix

// before
await page.locator('#save').click({ force: true }); // overlay covers it → throws
// after
await page.locator('#cookie-accept').click();
await page.locator('#save').click(); // auto-wait clears the overlay
Defensive patterns

Strategy: retry

Validate before calling

// Dismiss the overlay or remove force so auto-wait clears it.
await page.locator('#cookie-accept').click().catch(() => {});
await locator.click(); // no force → waits for nothing intercepting

Prevention

When it happens

Trigger: Calling a pointer action with force:true while a modal, tooltip, cookie banner, loading overlay, or sticky header sits on top of the target; an element momentarily covered by a transition.

Common situations: Cookie consent banners; full-screen loaders; `position:absolute` overlays; toast notifications appearing over the button under test when force was used to skip waiting.

Related errors


AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12). Data as JSON: /api/errors/b854edf063f0041a. Report an issue: GitHub.