Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The error pyppeteer.errors.ElementHandleError: Evaluation failed: SyntaxError: Unexpected token return means the JavaScript sent for evaluation contains a top-level return. JavaScript permits return only inside a function body. In the reported requests-html example, wrap the code in an arrow function and pass that complete function to render():

script = """() => {
    return Highcharts.charts[0].series[0].data.map(d => d.y);
}"""
chartdata = resp.html.render(script=script, reload=False)

This changes the input from an invalid top-level statement into a function expression whose return value the browser can send back to Python.

Why “Unexpected token return” happens

Pyppeteer evaluates JavaScript in a browser page. The browser parser sees return before it has entered a function, so it reports Unexpected token return. The problem is the form of the JavaScript input, not the value returned by Highcharts or another page script.

A top-level expression such as Highcharts.charts[0].series[0].data.map(d => d.y) can be valid JavaScript. A top-level return Highcharts... is not valid JavaScript because there is no enclosing function to return from.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Elebase USB to USB C Adapter for iPhone 18 Pro Max,USBC Car Charger Adapter
  • Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
  • Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
  • Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
  • Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
  • 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.

Invalid top-level form

return Highcharts.charts[0].series[0].data.map(d => d.y);

Valid function form

() => {
    return Highcharts.charts[0].series[0].data.map(d => d.y);
}

The distinction matters because wrappers do not necessarily parse a string in the same way. The accepted answer for the reported case demonstrates the arrow-function form for requests-html; it does not prove that every wrapper internally wraps strings identically.

Fix the reported requests-html call

  1. Build a complete function expression, including () => { and the closing brace.

  2. Keep the return inside that function body.

  3. Pass the function string to resp.html.render(script=..., reload=False).

from requests_html import HTMLSession

session = HTMLSession()
resp = session.get("https://example.com/chart")

script = """() => {
    return Highcharts.charts[0].series[0].data.map(d => d.y);
}"""

chartdata = resp.html.render(script=script, reload=False)
print(chartdata)

Replace the URL with your page. The page must have loaded Highcharts and populated Highcharts.charts[0]; otherwise the syntax error will be gone but a later runtime error may occur because the object does not exist.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why reload=False matters here

reload=False tells requests-html not to reload the page while rendering. It does not change JavaScript grammar and cannot make a top-level return legal. Keep it when you already have the desired page state; remove or change it only when your page requires a fresh navigation before the script runs.

Rank #2
Anker USB-C Hub, 5-in-1 USB Hub for Laptops, 4K HDMI Multiport Adapter
  • 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
  • 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
  • Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
  • 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
  • What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.

Expression versus function input

Evaluation APIs commonly support one or both of these shapes:

Input shape Example When to use it
Expression 1 + 2 Use when the API explicitly evaluates a JavaScript expression and you do not need a return statement.
Function () => { return 1 + 2; } Use when the API expects a callable function or when you need statements, local variables, conditionals, or an explicit return.

Pyppeteer 0.0.25 documents Page.evaluate as executing a JavaScript function or expression and returning the result. Its force_expr option, which defaults to False, controls expression treatment: force_expr=True forces expression mode. See the Pyppeteer 0.0.25 reference for the exact method signature and behavior.

If you are calling direct Pyppeteer rather than requests-html, check that method’s accepted input before changing the script. A string that works through one wrapper may be parsed differently by another.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Direct Pyppeteer examples

Evaluate a function

import asyncio
from pyppeteer import launch

async def main():
    browser = await launch()
    page = await browser.newPage()
    await page.goto("https://example.com/chart", {"waitUntil": "networkidle2"})

    values = await page.evaluate("""() => {
        return Highcharts.charts[0].series[0].data.map(d => d.y);
    }""")
    print(values)
    await browser.close()

asyncio.get_event_loop().run_until_complete(main())

Passing the function form makes the return context explicit and is generally easier to debug. Current Puppeteer documentation likewise describes Page.evaluate as accepting a function or string and recommends a function for easier debugging; its page identifies Puppeteer 25.12.0. That current JavaScript documentation is a comparison, not evidence that an older Python wrapper has identical internals. See Puppeteer Page.evaluate documentation.

Evaluate an expression instead

values = await page.evaluate(
    "Highcharts.charts[0].series[0].data.map(d => d.y)",
    force_expr=True,
)

Do not combine expression mode with a bare return. If you force expression mode, send the expression itself.

Rank #3
Sale
Anker USB C Hub, 7in1 Multi-Port USB Adapter, 4K@60Hz USBC to HDMI Splitter
  • Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
  • Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
  • Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
  • Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
  • What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.

A reliable debugging sequence

  1. Identify the actual caller. Determine whether the failing line is resp.html.render(script=...), page.evaluate(...), or another abstraction. The accepted fix is specifically demonstrated for the requests-html call.
  2. Print the exact JavaScript string. Hidden concatenation, indentation, or an accidentally truncated closing brace can change what reaches Chromium.
  3. Choose one input shape. Use () => { ... } with an internal return, or use a return-free expression. Do not paste a function body beginning with return where a complete function is required.
  4. Reduce the page expression. First evaluate typeof Highcharts, then Highcharts.charts.length, then the data mapping. This separates syntax problems from page-state problems.
  5. Capture the complete traceback. The first syntax correction may reveal a different error, such as an undefined object, a missing chart, or a navigation failure.
checks = await page.evaluate("""() => ({
    highchartsType: typeof Highcharts,
    chartCount: typeof Highcharts === 'undefined' ? 0 : Highcharts.charts.length
})""")
print(checks)

Common follow-up failures after the syntax fix

Highcharts is not defined

The chart library has not loaded in the page context, or the page uses a different charting library. Wait for the relevant script or inspect the page’s actual global names. This is a runtime/page-state issue, not the original parser error.

Cannot read properties of undefined

Highcharts.charts[0] may not exist yet. A navigation can finish before an application renders its chart. Wait for a chart-specific selector or poll for the object before evaluating the mapping.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The result is null or an empty array

The function executed, but the chart has no matching points at that moment. Confirm that the series is populated and that the page did not replace the chart after your evaluation.

The browser fails before evaluation

Record the Python package version, Pyppeteer version, Chromium revision, operating system, navigation URL, and full traceback. Pyppeteer 0.0.25 says it works best with its bundled Chromium and does not guarantee compatibility with other Chromium versions. A browser-version mismatch can produce failures unrelated to JavaScript syntax.

Version and wrapper checks

Use the environment that actually runs the failing code when diagnosing compatibility:

Rank #4
Sale
UGREEN USB to USB C Adapter Combo 4-Pack, 10Gbps USB C Converter Space Gray
  • Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
  • Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
  • Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
  • Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
  • Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft
python -m pip show pyppeteer requests-html
python --version

Also log the Chromium executable or revision selected by your installation. Do not assume that direct Pyppeteer, requests-html, and modern Puppeteer share the same argument parsing or browser support. The documented case establishes a working wrapper-specific function form, while the Pyppeteer reference documents the direct API’s function/expression options.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What not to change

  • Do not remove return from a multi-statement function merely to silence the parser; you may then lose the value you need.
  • Do not add force_expr=True to a wrapper that does not expose that option.
  • Do not diagnose a missing chart, blocked navigation, or incompatible Chromium as an “unexpected token” problem after the JavaScript parses successfully.
  • Do not assume a string accepted by one evaluation layer is passed unchanged to another layer.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If your goal is a clean image or PDF rather than extracting a JavaScript value, ScreenshotNeo provides a website screenshot API and MCP server. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing status in X-Page-Verdict and X-Billed headers.

One GET request returns PNG, JPEG, WebP, or PDF. The API supports full-page captures with lazy images loaded, CSS-selector element captures, dark mode, device presets or custom viewports, retina scale, PDF paper and margin controls, custom CSS and JavaScript, clicks, waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, configurable caching, signed links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, usage reporting, and an OpenAPI specification.

cURL

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

See the ScreenshotNeo API documentation for parameters and response handling. An MCP server supplies take_screenshot, get_page_info, and capture_pdf tools to Claude, Cursor, and other MCP clients, so an AI agent can capture pages without you maintaining a local Chromium setup.

The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan, and yearly billing gives two months free. Create a free ScreenshotNeo account.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Does adding parentheses around return fix the error?

No. Parentheses alone do not create a function. Pass a complete function such as () => { return value; }, or pass a return-free expression when the API supports expression input.

Best Value
Anker USB C Hub, 5-in-1 USBC to HDMI Splitter with 4K Display
  • 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
  • Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
  • Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
  • HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
  • What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.

Can I use an async arrow function?

Yes, when the evaluation API supports promises: use async () => { return await ...; }. Confirm that your specific wrapper awaits the returned promise.

Is this error caused by Highcharts?

Not in the reported case. The parser rejects the top-level return before Highcharts data is read. Highcharts loading or chart timing can cause separate runtime errors after the syntax is corrected.

Should I upgrade Pyppeteer immediately?

Not solely for this message. First correct the JavaScript input shape and identify your caller. Upgrade or change Chromium only after recording versions and investigating a separate compatibility or browser-launch failure.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The Bottom Line

Put return inside a function passed to the evaluation API. For the reported requests-html call, the working shape is () => { return ...; }; if the error persists, inspect the exact caller, JavaScript string, page state, and Chromium versions.

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.