How to Get the Frame from a Puppeteer Console Message
Puppeteer’s ConsoleMessage has no documented frame() method. Learn how to inspect the frame tree and use message locations for best-effort attribution.
Puppeteer’s documented ConsoleMessage API does not provide a frame() method. A console message exposes its text, type, arguments, source location, and stack trace. You can compare the message’s location URL with the URLs of the page’s current frames to find candidate frames, but that is a heuristic, not a guaranteed mapping. When you need dependable attribution, record it in your own application-level logging.
1. What a Puppeteer console message tells you
A ConsoleMessage is delivered through the page’s console event. Its documented methods include text(), type(), args(), location(), and stackTrace(). The API reference does not list a method that returns the originating Frame. The location and stack entries contain source-location information; they are not frame objects.
Puppeteer ConsoleMessage API reference, stackTrace() reference, and ConsoleMessageLocation reference.
2. Best-effort URL matching
For a quick clue, compare message.location().url with the URLs from page.frames(). Treat matches as candidates only. Frames can share a URL, a frame may navigate after the message was emitted, and a source location may not uniquely identify a frame.
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
page.on('console', message => {
const location = message.location();
const candidateFrames = page.frames().filter(
frame => frame.url() === location.url
);
console.log({
text: message.text(),
type: message.type(),
location,
candidateFrames: candidateFrames.map(frame => ({ url: frame.url() })),
});
});
await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
await page.evaluate(() => console.warn('Example console message'));
} finally {
await browser.close();
}
})();
This is runnable with a Node.js project that has Puppeteer installed. It logs candidate URLs rather than claiming the matching frame is definitively the source. Depending on the console call, location data can be absent or insufficient; inspect the returned location before assuming url is usable.
3. Inspect the current frame tree
Use page.mainFrame() for the main document and Frame.childFrames() to walk its descendants. This shows the current hierarchy, which is useful for debugging iframe setup independently of a particular console message.
function dumpFrameTree(frame, indent = '') {
console.log(`${indent}${frame.url()}`);
for (const child of frame.childFrames()) {
dumpFrameTree(child, `${indent} `);
}
}
dumpFrameTree(page.mainFrame());
The frame tree can change as the page adds, removes, or navigates frames. Puppeteer’s Frame API reference documents the frame methods, including url(), parentFrame(), childFrames(), and evaluate().
4. Keep exact attribution in application logging
If you control the code that emits the message, include a stable application-level identifier in the log record and associate it with the frame or page context at the point where you create the handler. This avoids trying to reconstruct identity later from a URL that may be shared or already changed. The documented public API references do not establish an exact ConsoleMessage-to-Frame accessor.
If exact attribution is essential for code you do not control, investigate protocol-level facilities for the exact Puppeteer version you run. Treat that as a version-specific implementation path and verify its support and behavior against that version; it is not a documented ConsoleMessage feature in the references above.
5. Reliability, performance, and version notes
- Reliability: URL equality is useful only as a clue. Duplicate URLs and navigation races make it ambiguous. Preserve your own context if you require authoritative attribution.
- Performance: Calling
page.frames()and comparing URLs is a small scan of the current frame list. For pages with many frames or frequent console events, avoid repeatedly dumping the entire tree; log only the fields needed and inspect the tree when debugging. - Version: Puppeteer APIs evolve. The Frame reference reviewed for this article identifies version 25.12.0. Check the API reference matching your installed release before relying on version-specific behavior.
- Scope: This advice concerns Puppeteer’s documented JavaScript API. The API references do not specify when each relevant method was introduced.
6. Troubleshooting
| Symptom | Likely cause | What to do |
|---|---|---|
message.frame is not a function |
ConsoleMessage has no documented frame() method. |
Read message.location() and compare its URL to current frame URLs as a best-effort clue. |
| No candidate frame matches | The location URL may be empty or differ from the frame URL; the frame may have navigated or gone away. | Log the full location object and current frame tree. Do not interpret no match as proof the message came from the main frame. |
| Several candidates match | Multiple frames can use the same URL. | Keep the result ambiguous. Capture attribution in application-level logging if you control the source. |
| The frame tree differs between logs | Frames can be created, detached, or navigated while the page runs. | Inspect the tree near the event and account for navigation timing; a later snapshot describes current state, not necessarily event-time state. |
| Stack trace does not identify a frame | stackTrace() provides location entries, not a documented Frame mapping. |
Use it for source-location clues, not as proof of frame identity. |
7. Or skip the browser setup
If your goal is a screenshot of the page or one of its rendered states, ScreenshotNeo provides a website screenshot API and MCP server. It does not expose Puppeteer console-message frame attribution; use the Puppeteer approach above for that debugging task.
One GET request returns an image or PDF. See the ScreenshotNeo API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://example.com \
-o shot.webp
ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before capture. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up free and get 1,000 screenshots a month with no card.
8. FAQ
Does Puppeteer ConsoleMessage have a frame method?
No such method appears in the documented ConsoleMessage API. Use location data as a clue and inspect the page’s frame tree separately.
Can I tell which iframe logged a message?
Sometimes you can identify candidate frames by matching source and frame URLs, but the documented APIs do not guarantee unique attribution.
Does stackTrace() return Frame objects?
No. It returns console message location entries, not Frame instances.


