Skip to content
Playwright · error message

Playwright: ... intercepts pointer events (retrying click action)

RetryableActionability & click timeouts

Last verified

The exact message
TimeoutError: locator.click: Timeout 30000ms exceeded. Call log: - waiting for getByRole('button', { name: 'Checkout' }) - locator resolved to <button class="btn">Checkout</button> - attempting click action - waiting for element to be visible, enabled and stable - element is visible, enabled and stable - scrolling into view if needed - done scrolling - <div class="cookie-overlay">…</div> intercepts pointer events - retrying click action

What it means

This line in the call log is the most common reason behind a click timeout. Before clicking, Playwright hit-tests the exact point it is about to click. If the topmost element at that point is not the target or one of its descendants, a real user's click would land on something else, so Playwright refuses, logs which element is in the way, and retries until the timeout.

A variant reads ... from <div> subtree intercepts pointer events, which means the blocking element is inside another container, often a modal root or portal. The described element is the one to look at; it is usually an overlay, a backdrop, a sticky header or a spinner.

What is not wrong: the locator resolved, and the element is visible, enabled and stable. Only the receives-events check is failing.

What it looks like

// Wait for the spinner to go, then click
await expect(page.locator('.loading-overlay')).toBeHidden();
await page.getByRole('button', { name: 'Checkout' }).click();

// Auto-dismiss a cookie banner whenever it shows up
await page.addLocatorHandler(
  page.getByRole('button', { name: 'Accept all' }),
  async btn => { await btn.click(); },
);

Why it happens

  • A cookie-consent banner, newsletter modal or chat widget covers the target.
  • A loading spinner or transparent backdrop remains after a request or animation.
  • A sticky header or footer overlaps the element after it is scrolled into view.
  • Custom form controls hide the real input under a styled label or span (common with checkboxes and selects in component libraries).
  • A disabled-looking layer is drawn over the form until validation passes.

How to fix it

  1. Read which element the call log names; inspect it in the trace snapshot to see what it is.
  2. Dismiss or wait out the overlay: click its close or accept button, or await expect(overlay).toBeHidden().
  3. For overlays that appear unpredictably, register page.addLocatorHandler(overlayLocator, handler).
  4. For styled checkboxes, click the label (getByLabel) or use locator.check() on the input, which accounts for associated labels.
  5. Use force: true only when you have confirmed the overlay is cosmetic; it skips the safety check entirely.

How to stop it recurring

Set consent cookies or storage state up front so banners never render in automated runs. Wait for application-level readiness (spinners hidden, data loaded) after every action that triggers a request. Treat force: true as a debugging tool, not a fix, because it will happily click through a real blocking dialog.

Official documentation: playwright.dev/docs/actionability#receives-events. See all Playwright error messages.

Related errors

Definitions

Quick answers

What does "... intercepts pointer events (retrying click action)" mean in Playwright?

This line in the call log is the most common reason behind a click timeout. Before clicking, Playwright hit-tests the exact point it is about to click. If the topmost element at that point is not the target or one of its descendants, a real user's click would land on something else, so Playwright refuses, logs which element is in the way, and retries until the timeout. A variant reads ...

How do I fix "... intercepts pointer events (retrying click action)"?

1. Read which element the call log names; inspect it in the trace snapshot to see what it is. 2. Dismiss or wait out the overlay: click its close or accept button, or await expect(overlay).toBeHidden(). 3. For overlays that appear unpredictably, register page.addLocatorHandler(overlayLocator, handler). 4. For styled checkboxes, click the label (getByLabel) or use locator.check() on the input, which accounts for associated labels. 5. Use force: true only when you have confirmed the overlay is cosmetic; it skips the safety check entirely.

Run browser automation you can watch and take over

Autonoly runs each job in a real cloud Chromium browser driven by Playwright. Timeouts and detached elements still happen; the difference is that you can watch the run live, see the step that failed, and take control of the browser to finish it.

Also see Live browser control.