How to Access Arguments from a Puppeteer Console Message
Read individual browser console arguments in Puppeteer with `msg.args()`, then resolve serializable values with `jsonValue()` or inspect handles in the page context.
Listen for the page’s console event and call args() on its ConsoleMessage. This returns an array of JSHandle objects, one for each argument passed to the browser’s console method. For ordinary serializable values, call jsonValue() on each handle.
page.on('console', async msg => {
const values = await Promise.all(msg.args().map(arg => arg.jsonValue()));
console.log(values);
});
msg.text() is useful when you only need Puppeteer’s formatted message string. Use msg.args() when you need the individual values and their types. See the official Puppeteer ConsoleMessage API.
1. Capture console arguments with Puppeteer
Register the listener before navigating or evaluating code that might log during page initialization. The handler receives console calls and can also receive warnings and errors, so check msg.type() if you only want a particular kind of message.
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
page.on('console', async msg => {
try {
const args = await Promise.all(msg.args().map(arg => arg.jsonValue()));
console.log({
type: msg.type(),
text: msg.text(),
args,
location: msg.location(),
});
} catch (error) {
console.error('Could not resolve every console argument:', error);
console.log('Message text:', msg.text());
}
});
await page.goto('https://example.com');
await page.evaluate(() => console.log(5, 'hello', { foo: 'bar' }));
await browser.close();
Save this as an ES module (for example, console-args.mjs) in a project where Puppeteer is installed, then run it with node console-args.mjs. The example logs the message type, formatted text, resolved arguments, and source location. The official Page API documents page evaluation, while the Puppeteer API index describes handles.
Filter by console method
Use the message type to ignore warnings, errors, or other console methods. The exact type values follow Puppeteer’s ConsoleMessage API.
page.on('console', async msg => {
if (msg.type() !== 'log') return;
const args = await Promise.all(msg.args().map(arg => arg.jsonValue()));
console.log(args);
});
Use an event promise for one expected message
If your script triggers one known console call and needs its values, create the event promise before triggering the call. This avoids missing a message emitted synchronously during evaluation.
const consoleMessage = new Promise(resolve => {
page.once('console', resolve);
});
await page.evaluate(() => console.log('ready', { count: 3 }));
const msg = await consoleMessage;
const args = await Promise.all(msg.args().map(arg => arg.jsonValue()));
console.log(args);
2. Choose between text, values, and handles
| Need | Use | What you get |
|---|---|---|
| Readable formatted output | msg.text() |
A string representation of the console message. |
| Individual arguments | msg.args() |
An array of handles tied to values in the browser context. |
| Plain values in Node.js | handle.jsonValue() |
A serialized value when the argument can be transferred as a value. |
| Selected properties or browser-only objects | handle.evaluate(fn) |
The result of inspecting the referenced object in the page context. |
args() does not return ordinary Node.js objects. A handle is a reference to an object in the page’s JavaScript context. Serialization is convenient for numbers, strings, booleans, arrays, and plain objects, but browser objects and values that do not serialize as expected require page-context inspection. Avoid assuming every argument can be copied intact into Node.js.
Inspect an object in the page context
For an object with a useful subset of fields, evaluate against the handle and return only those fields:
page.on('console', async msg => {
const handles = msg.args();
const first = handles[0];
if (!first) return;
const summary = await first.evaluate(value => ({
type: typeof value,
tagName: value instanceof Element ? value.tagName : undefined,
keys: value && typeof value === 'object'
? Object.keys(value).slice(0, 20)
: [],
}));
console.log(summary);
});
Choose fields deliberately: returning a DOM node or another browser-only object as though it were a plain JSON value can fail or lose information. For a complete DOM snapshot, query the needed properties in the page context and return a compact serializable result.
3. Complete runnable examples in other languages
The console event and ConsoleMessage handles are Puppeteer’s Node.js API. cURL and Python can request a screenshot, but they cannot subscribe to a Puppeteer page’s console event or retrieve its JSHandles. If the task is to inspect console arguments, use Puppeteer in Node.js. The following examples show the equivalent screenshot request when the goal is a page image rather than console debugging.
cURL: request a screenshot
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://example.com \
-o shot.webp
Python: request a screenshot
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://example.com"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
Node.js: request a screenshot
const q = new URLSearchParams({
access_key: 'YOUR_API_KEY',
url: 'https://example.com'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await import('node:fs/promises').then(({ writeFile }) =>
writeFile('shot.webp', Buffer.from(await res.arrayBuffer()))
);
For API parameters and supported capture options, see the ScreenshotNeo documentation.
4. Common errors and fixes
| Symptom | Cause | Fix |
|---|---|---|
args contains objects that are not usable as plain values |
args() returns JSHandles, not materialized Node.js values. |
Resolve ordinary values with jsonValue(); use evaluate() on a handle to select properties in the page context. |
| No event arrives | The listener was attached after the console call, or the page did not execute the code that logs. | Register page.on('console', ...) before navigation or evaluation; confirm the page code ran. |
| Handler receives warnings or errors too | The console event covers more than console.log. |
Check msg.type() and return early for types you do not need. |
| One argument cannot be serialized | The argument is a browser object or another value that does not round-trip as a plain value. | Inspect it with handle.evaluate() and return only serializable fields. Keep the handle scoped to the message handler. |
| The capture script misses an early initialization message | The page emitted it before the listener was attached. | Attach the listener before calling goto(); for one event, create the promise before the action. |
5. Performance, reliability, and cost
Resolving every argument adds asynchronous work to the event handler. For busy pages, filter on msg.type() first, then resolve only messages you need. Avoid retaining handles after the message has been processed; extract the needed values and let temporary references go. If a page produces many messages, keep logging bounded and avoid expensive full-object inspection in every callback.
For reliable capture, attach the listener before navigation, handle promise rejections inside the callback, and close the browser in a finally block in long-running scripts. Navigation may produce several console events, so do not assume the first event is your application’s message; filter by type or by a recognizable argument when appropriate.
With self-hosted Puppeteer, account for the browser process and the compute resources needed to run it; there is no per-console-message fee defined by Puppeteer in the cited API material. If you only need a page screenshot and not browser-side console values, ScreenshotNeo provides a screenshot API and MCP server, with usage-based plans described below.
6. Or skip the browser setup
If your goal is to capture the rendered page rather than inspect JavaScript console arguments, ScreenshotNeo takes a screenshot with one GET request. It accepts cookie and consent banners before capture and removes 60+ known consent platforms, newsletter popups, and chat widgets; each step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and the response identifies the page verdict and billing status in headers. Its MCP server gives AI agents screenshot, page-info, and PDF capture tools.
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 API documentation for options and response details. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account to get an API key.
7. FAQ
Does args() return the original JavaScript values?
It returns handles for the arguments. Resolve serializable values with jsonValue(), or inspect a handle in the page context.
When should I use text() instead?
Use it when a formatted string is enough and you do not need separate argument values or types.
Can I get the console call’s source location?
Yes. msg.location() provides location information, and msg.stackTrace() provides stack trace details where available. See the ConsoleMessage API.
Can cURL or Python read Puppeteer console arguments?
No. Those tools can make HTTP requests, but Puppeteer’s console event and JSHandles are available through Puppeteer’s Node.js page API.


