Puppeteer: Node is either not clickable or not an Element
Last verified
Error: Node is either not clickable or not an ElementWhat it means
Before clicking, hovering or tapping, Puppeteer computes a clickable point inside the element using its content quads and the viewport. This error means it could not find any part of the element that is both rendered and inside the layout viewport, so there is nowhere to send the mouse event. It is the current-version counterpart of the older Node is either not visible or not an HTMLElement click error.
Elements with zero size, display: none, or that are clipped away entirely produce it. So do elements that exist in the DOM but are not laid out yet, such as content inside a template, a closed dialog, or a collapsed panel. Puppeteer scrolls the element into view first, so an element that is merely below the fold is not the problem.
What is not wrong: the element handle is valid and attached. It just has no visible area to click.
What it looks like
// Locator API waits for visible, enabled and stable before clicking
await page.locator('::-p-aria(Save[role="button"])').click();
// Equivalent with an explicit wait
const btn = await page.waitForSelector('button.save', { visible: true });
await btn.click();Why it happens
- The element is hidden, zero-sized, or inside a collapsed or closed container.
- The selector matched a hidden duplicate instead of the visible element.
- The element is fully clipped by an overflow:hidden ancestor or positioned off-canvas.
- The handle points to a non-element node, for example from an XPath that selected a text node.
How to fix it
- Wait for visibility before clicking: await page.waitForSelector(selector, { visible: true }), or use page.locator(selector).click().
- Narrow the selector to the visible instance, for example with ::-p-aria(Submit[role="button"]).
- Open the menu, dialog or panel that contains the element first.
- If the XPath selects text, select the parent element instead (::-p-xpath(//button[contains(., 'Save')])).
How to stop it recurring
Prefer the Locator API for interactions; it re-queries the page and checks visibility and stability before every action. Choose selectors that describe what the user sees, such as ARIA names, so they cannot match hidden copies. Reveal containers (menus, dialogs, tabs) as an explicit step before interacting with their contents.
Official documentation: pptr.dev/api/puppeteer.elementhandle.clickablepoint. See all Puppeteer error messages.
Related errors
Definitions
- PuppeteerPuppeteer is Google's open-source Node.js library for controlling Chrome and Firefox. It drives Chrome over th
- Chrome DevTools Protocol (CDP)The Chrome DevTools Protocol (CDP) is the JSON-over-WebSocket interface Chrome exposes for inspecting and cont
- CSS SelectorA CSS selector is a pattern used to identify and target specific HTML elements on a web page, widely used in b
- Headless ChromeHeadless Chrome is Google Chrome running without a visible window. It renders pages and runs JavaScript like n
- IframeAn iframe (inline frame) is an HTML element that embeds a separate web page within a parent page, creating an
- Web ElementA web element is any individual component rendered on a web page — buttons, links, input fields, images, text
Quick answers
What does "Node is either not clickable or not an Element" mean in Puppeteer?
Before clicking, hovering or tapping, Puppeteer computes a clickable point inside the element using its content quads and the viewport. This error means it could not find any part of the element that is both rendered and inside the layout viewport, so there is nowhere to send the mouse event. It is the current-version counterpart of the older Node is either not visible or not an HTMLElement click error.
How do I fix "Node is either not clickable or not an Element"?
1. Wait for visibility before clicking: await page.waitForSelector(selector, { visible: true }), or use page.locator(selector).click(). 2. Narrow the selector to the visible instance, for example with ::-p-aria(Submit[role="button"]). 3. Open the menu, dialog or panel that contains the element first. 4. If the XPath selects text, select the parent element instead (::-p-xpath(//button[contains(., 'Save')])).
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.