Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Use handle.asElement() to check whether an existing Puppeteer JSHandle already refers to a DOM element. It returns an ElementHandle when it does, or null when it does not. To obtain a handle to an element from page code, use page.evaluateHandle() instead.
Check an existing handle with asElement()
asElement() is a runtime check, not a conversion of an arbitrary JavaScript object into a DOM node. If the value behind the handle is already an element, Puppeteer returns that same handle as an ElementHandle; otherwise it returns null. See the Puppeteer JSHandle.asElement() reference.
const element = handle.asElement();
if (element === null) {
throw new Error('Handle does not refer to an element');
}
await element.click();
Always check for null before calling element-specific methods such as click(). The method’s documented return type is ElementHandle<Node> | null.
Get an element handle from page code
If your current handle is not an element—or you have not obtained a handle yet—evaluate page code that selects or derives the element, and retain the result with evaluateHandle(). A returned DOM element is represented at runtime by an ElementHandle.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
#1 Best Overall
const handle = await page.evaluateHandle(() =>
document.querySelector('#submit')
);
const element = handle.asElement();
if (element === null) {
throw new Error('The selector did not return an element');
}
await element.click();
The selector can return null when no matching element exists, so this check covers both a missing match and a result that is not an element. The Puppeteer Page.evaluateHandle() reference documents retained handles and the TypeScript generic form for callers who know the result is an element. Check the overloads for the Puppeteer version installed in your project.
Evaluate from an existing handle
When you need to derive an element starting from an existing handle, use that handle’s evaluateHandle() method to run page code in the context of its referenced object. The returned object remains a handle; narrow it with asElement() and check for null before using element methods. See the Puppeteer JSHandle reference.
Rank #2
Choose between evaluate() and evaluateHandle()
- Use
evaluateHandle()when later operations need to act on the page object itself, such as clicking a selected element. - Use
evaluate()when you need ordinary serializable data, such as text or an attribute value. It returns the result rather than retaining a handle. Returning a DOM node throughevaluate()does not give you a usable element handle; the JavaScript execution guide illustrates that a returneddocument.bodycan serialize as{}. See Puppeteer’s JavaScript execution guide.
Find element-valued properties on a handle
If a handle refers to an object whose properties may contain DOM elements, call getProperties() to get handles for those properties, then narrow each one with asElement(). Retain only non-null results:
const properties = await objectHandle.getProperties();
const elements = [];
for (const propertyHandle of properties.values()) {
const element = propertyHandle.asElement();
if (element !== null) {
elements.push(element);
}
}
Puppeteer documents this approach for collecting element-valued properties, including children of document.body, in its JSHandle.getProperties() reference.
Handle lifetime and cleanup
A JSHandle keeps its referenced page object from being garbage-collected while the handle remains active. Call dispose() when you no longer need a retained handle. Puppeteer also disposes handles automatically when their frame navigates away or their parent execution context is destroyed. These lifecycle details are documented in the JSHandle reference.
const handle = await page.evaluateHandle(() => document.querySelector('button'));
try {
const element = handle.asElement();
if (!element) throw new Error('No button element was returned');
await element.click();
} finally {
await handle.dispose();
}
Troubleshoot a missing or unusable element handle
| Symptom | Likely cause | What to do |
|---|---|---|
asElement() returns null |
The handle refers to a non-element value, or the evaluated selector returned null. |
Check what the page expression returns and confirm the selector matches an element. If you need a DOM element, use evaluateHandle() with an expression that returns it. |
| A returned node is not usable with element methods | The code used evaluate(), which returns a serialized value rather than retaining the page object. |
Use evaluateHandle() to retain the reference, then call asElement(). |
| A handle becomes unusable after navigation or context destruction | Puppeteer disposes handles associated with the old frame or execution context. | Run the evaluation again in the current page context to obtain a fresh handle. |
| A TypeScript call does not match the expected overload | The generic or overload available may differ in the installed Puppeteer version. | Check the API documentation and type declarations for your installed release; documentation labels can refer to different versions. |
Or skip the browser setup
If what you need is a rendered page screenshot rather than an in-page element handle, ScreenshotNeo provides a one-call screenshot API and an MCP server for AI agents. Cookie banners, newsletter popups and chat widgets are removed before capture; bot checks, blank pages and failed loads are not billed; and the MCP server lets AI agents take screenshots.
One-call cURL example (see the ScreenshotNeo API documentation):
Rank #4
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Sign up for 1,000 free screenshots a month, with no card.
Quick Recap
Best Value
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

