The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →The message Cannot extract value when objectId is given means Puppeteer is trying to extract a value from a remote object reference where that extraction path expects a value returned by value. If you already have an element or JavaScript handle, call its public jsonValue() method when you need serializable data, then dispose of the handle. If you do not need a handle, return the data directly from page.evaluate().
The error text does not, by itself, identify the line or call that triggered it. Check the code around your evaluate() and evaluateHandle() calls and confirm whether the result you need is a value or a handle.
As an Amazon Associate I earn from qualifying purchases.
Choose the API that matches the result you need
Puppeteer can return data from page code in two useful forms:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
page.evaluate()returns a serializable result directly. Use it when you need data such as a string, number, array, or plain object and do not need to keep a remote reference to a page object.page.evaluateHandle()returns a handle to a remote object. Use the handle when you need to keep working with that object in the page. If you later need its serializable value, calljsonValue()on the handle.
The error reference describes objectId as the identifier for a remote reference, while the primitive-value extraction path expects a by-value result. That explanation fits the mismatch indicated by the error, but the message alone cannot show which call in your program caused it.
#1 Best Overall
Fix an existing handle with jsonValue()
If your code already has a handle and needs its serializable value, extract the value through the handle’s public API and dispose of the handle when finished:
const handle = await page.evaluateHandle(() => ({ count: 3 }));
try {
const value = await handle.jsonValue();
console.log(value);
} finally {
await handle.dispose();
}
jsonValue() gives you the serializable value represented by the handle. The finally block ensures the handle is released even if value extraction or later work throws an error.
Rank #2
Use evaluate() when you only need a value
If you do not need to retain a remote object handle, return the serializable data directly from page.evaluate():
const value = await page.evaluate(() => ({ count: 3 }));
console.log(value);
Use this approach for results that can be serialized and passed back from the page. Keep evaluateHandle() for cases where you need to continue interacting with the page-side object rather than immediately receiving its value.
Rank #3
Trace the mismatch in your code
- Find the failing call. Read the stack trace and inspect the surrounding code for
page.evaluate(),page.evaluateHandle(), or handle-value extraction. - Identify what the code expects. If the next step needs ordinary serializable data, use
evaluate()or calljsonValue()on the existing handle. - Check the returned type. Confirm whether the expression returns a page-side value or a handle, and whether later code treats it accordingly.
- Release handles. Call
dispose()once you no longer need a handle, preferably in afinallyblock when cleanup must happen even after an error.
An error reference illustrates the shape of a handle by calling remoteObject() on one returned by evaluateHandle(). That illustration is not a guaranteed reproduction of this error, and it does not show that normal use of evaluateHandle() is inherently incorrect. Public handle methods are intended to route handle operations appropriately.
What not to change blindly
A historical Puppeteer issue from 2021 contains the same assertion in older helper code, but its author said the issue could not be reproduced. The report mentions a timeout and a previous setDefaultTimeout(0) adjustment; it does not establish that changing timeout settings fixes this object-ID error. Do not disable or extend timeouts as a substitute for checking whether your code is handling a value or a handle.
Rank #4
A historical Mozilla Bugzilla report also records a case where Runtime.evaluate returned an object ID instead of a value and an older Puppeteer stack hit the assertion. This illustrates the general mismatch, but it does not diagnose a current program or browser version.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchPC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Troubleshooting common cases
| Symptom or situation | What to check | What to do |
|---|---|---|
| You need an object’s serializable contents, but you already have a handle. | Check whether the code is trying to extract a primitive or value through a lower-level or mismatched path. | Call handle.jsonValue(), then dispose of the handle when finished. |
| You only need data returned from a page expression. | Check whether the code creates a handle unnecessarily. | Return the serializable result directly with page.evaluate(). |
| The error appears after changing a timeout. | Do not assume the timeout change caused or fixed the object-ID mismatch; a historical report does not establish that relationship. | Inspect the failing call and the result type. Keep timeout configuration separate unless there is an independently diagnosed timeout problem. |
| The problem persists or the failing call is unclear. | Version-specific behavior and the exact initiating call cannot be determined from the error string alone. | Collect the Puppeteer and browser versions, a minimal snippet around the relevant evaluate() or evaluateHandle() call, the intended result shape, and the full stack trace. |
Or skip the browser setup
If the task is to capture a website rather than debug a Puppeteer script, ScreenshotNeo offers a screenshot API and MCP server for developers. Its API can return a screenshot or PDF from one GET request. Cookie and consent banners, newsletter popups, and chat widgets are removed before capture; each cleanup step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and responses identify the page verdict and billing status in headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for AI agents and MCP clients.
Example cURL request, using the documented API parameters:
Best Value
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for request options and setup. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Sign up for ScreenshotNeo’s free plan.
Frequently Asked Questions
Does this error mean every use of evaluateHandle() is wrong?
No. A handle is appropriate when you need a remote page-side object. The issue is whether the code uses a value-extraction path that matches the kind of result it has.
Can I fix this error by setting Puppeteer’s timeout to zero?
The historical timeout report does not show that timeout configuration resolves this error. Inspect the value-versus-handle handling instead.
What details should I include when asking for help with this error?
Include the Puppeteer and browser versions, the smallest relevant code snippet, the result shape you intended, and the full stack trace.
Quick Recap
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.




