The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Debug Puppeteer by first identifying which layer is failing: your Node.js script, code running in the page, the Chrome process, or communication between Puppeteer and Chrome. Then collect evidence from that layer. A visible browser and a saved screenshot expose rendering and timing problems; browser DevTools and Node’s inspector let you pause at the relevant code; protocol logs and browser-process output help explain hangs and launch failures.
Start by identifying the failing layer
Puppeteer sits between a Node.js program and a browser, while the page itself runs its own JavaScript and makes network requests. A failure that looks like “Puppeteer is stuck” may therefore come from different places. The Puppeteer project’s debugging guide notes that there is no single debugging method for every issue because the system spans browser requests, Web APIs, Node.js code, and browser internals.
- Node.js orchestration: the script did not reach an awaited call, is waiting on the wrong condition, or has an exception in its own logic.
- Page code or rendering: the page failed to load or render as expected, a client-side script threw, or a selector is absent.
- Browser process: Chrome or Chromium cannot start, exits unexpectedly, or reports an environment problem.
- DevTools Protocol: Puppeteer sent a browser command that has not returned, or the connection between Node and the browser is unhealthy.
Write down the last operation that completed and the first one that did not. That boundary is more useful than treating every timeout as a generic Puppeteer error.
Make the browser’s behavior visible
For an intermittent click, navigation, or typing issue, start with the simplest observation: run the browser with its UI visible and slow the automation down. This is a diagnostic setup, not a production setting.
#1 Best Overall
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
headless: false,
slowMo: 250,
});
try {
const page = await browser.newPage();
await page.goto('https://example.com');
await page.screenshot({ path: 'debug.png', fullPage: true });
} finally {
await browser.close();
}
})();
Run it with node script.js. The visible window shows whether the browser reached the expected page and whether an overlay, redirect, or unexpected state changed what the automation sees. slowMo adds a delay between Puppeteer operations, making sequences easier to watch; it also makes the run slower, so remove it after diagnosis. A screenshot preserves the rendered state for later inspection, including cases that are too brief to catch by eye.
Debug JavaScript running inside the page
Code passed to page.evaluate() runs in the browser context, not in Node.js. As a result, a browser-side console.log() does not automatically appear in your terminal. Forward page console messages explicitly:
page.on('console', msg => console.log('PAGE LOG:', msg.text()));
page.on('pageerror', error => console.error('PAGE ERROR:', error));
await page.evaluate(() => {
console.log(`url is ${location.href}`);
});
Register these listeners before navigation or evaluation so early messages are not missed. The pageerror listener is useful for uncaught exceptions; console forwarding makes deliberate logging visible in Node. For failed requests, add a request-failure listener when network behavior is relevant:
page.on('requestfailed', request => {
console.error('REQUEST FAILED:', request.url(), request.failure()?.errorText);
});
To pause at a specific point in browser-side code, launch with devtools: true and put a debugger statement inside the function evaluated in the page:
Rank #2
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
const browser = await puppeteer.launch({
headless: false,
devtools: true,
});
const page = await browser.newPage();
await page.evaluate(() => {
debugger;
console.log('The page debugger can pause here');
});
When execution reaches debugger, Chrome DevTools can pause and let you inspect the page’s variables and execution state. This is the right tool for DOM, browser API, and client-side logic questions; it will not step through the Node.js code that called page.evaluate().
Debug the Node.js script with the inspector
Use Node’s inspector when the issue is in orchestration: for example, a script does not reach page.click(), uses the wrong variable, or appears to wait at an await. Put a debugger; statement in the Node code, launch the test browser headful, then start the script with:
node --inspect-brk path/to/script.js
- Open
chrome://inspect/#devicesin Chrome. - Find the Node target and click inspect.
- In the DevTools window, press F8 to resume from the initial pause.
- Use the debugger controls to step through the script and inspect local variables around the failing operation.
--inspect-brk pauses Node at startup, which gives you time to attach the debugger. With the browser visible as well, you can correlate a Node call with what the page is doing. If the test works only when the inspector is attached, consider whether the extra time changes a race or timeout rather than assuming the debugger fixed the underlying issue.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Investigate hangs and protocol calls
If an asynchronous Puppeteer operation never resolves and ordinary logging does not identify the boundary, enable Puppeteer’s internal debug output:
Rank #3
env NODE_DEBUG="puppeteer:*" node script.js
This logs internal Puppeteer and DevTools Protocol activity, which can help establish whether a command was sent and whether a response arrived. The output can be large and may contain sensitive information. Avoid publishing it unredacted, especially if the run uses authenticated pages, cookies, or private URLs.
For unresolved protocol calls, inspect browser.debugInfo.pendingProtocolErrors. The pending errors include stack traces pointing to the code that initiated the protocol call. Use that stack to locate the operation in your script, then compare it with the last protocol messages in the debug log. The goal is to determine whether your code is awaiting a condition that never becomes true or whether the browser command itself remains outstanding.
Find browser launch and crash failures
When Chrome fails to launch or exits unexpectedly, forward its output to the Node process rather than looking only at the Puppeteer exception:
const browser = await puppeteer.launch({ dumpio: true });
dumpio: true forwards browser logs to Node’s standard streams. Preserve the full error and stack trace, and record the Puppeteer version, browser version, operating system, and operation being attempted. Those details help distinguish an install problem from a browser incompatibility or an application bug.
Rank #4
- Brand: Wiley
- Set of 2 Volumes
- A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers
Check that the browser was installed where Puppeteer expects
Since Puppeteer v19, its downloaded browsers normally use ~/.cache/puppeteer. If an application runs under a different user, in a container, or with a custom cache location, the browser may not be present in the environment that launches the script. PUPPETEER_CACHE_DIR can relocate the cache. Confirm that the install and runtime use the same configured location.
Check whether the package manager blocked installation
Some package-manager configurations prevent package install scripts from running, which can leave Puppeteer installed without its browser download. Run npx puppeteer browsers install in the project environment or allow the Puppeteer install script, then retry. Do not assume a successful npm package installation proves a usable browser binary is available.
Check platform permissions and compatibility
- Windows sandbox permissions: newer Puppeteer versions attempt setup automatically, but older versions or restricted environments may still need executable permission fixes. Use the guidance for the exact version and environment rather than copying a permission workaround blindly.
- Alpine Linux: Chrome is not supported out of the box. Chromium and Puppeteer versions need to be compatible. The Puppeteer troubleshooting guide has also noted a Chromium 3.20 timeout issue with a 3.19 downgrade workaround for the version context described there; treat that as a version-specific compatibility case, not a general Alpine fix.
- Extensions and managed policies: Puppeteer disables extensions by default. If a managed Chrome policy requires extensions, the launch configuration may need
enableExtensions: true.
Version-specific workarounds age quickly. Match any troubleshooting advice to your installed Puppeteer and browser versions, and prefer correcting the underlying environment over adding launch flags that mask the actual cause.
Capture evidence for rendering and performance problems
Use a screenshot when you need to see what the page looked like at the failure point. Save it immediately after the operation under investigation or after a catch block that records the current URL and state. A full-page capture can reveal content farther down the document; a viewport capture is often more useful for a particular interaction. Screenshots may contain personal or confidential page data, so handle and store them accordingly.
Best Value
For a slow page or a sequencing problem that is hard to explain from logs, record a trace:
await page.tracing.start({ path: 'trace.json' });
try {
await page.goto('https://example.com');
await page.waitForSelector('main');
} finally {
await page.tracing.stop();
}
The resulting trace can be opened in Chrome DevTools or a timeline viewer to inspect the sequence and timing of browser activity. Tracing adds overhead and creates a file that may contain details about the page and its requests. Keep the trace focused on the action you need to diagnose, and do not leave tracing enabled for routine runs without a reason.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Choose the diagnostic by symptom
| Symptom or question | First technique | Evidence it provides | Trade-off |
|---|---|---|---|
| Clicks or navigation happen too quickly to observe | headless: false and a small slowMo |
Visible browser state and action order | Slower run; timing may differ from production |
| A selector or page script behaves unexpectedly | Page console and page-error listeners; browser DevTools for breakpoints | Client-side messages, exceptions, and paused page execution | Requires a visible browser for interactive inspection |
| The Node script does not reach or complete an operation | node --inspect-brk and chrome://inspect/#devices |
Call stack, variables, and control flow | Attaching the debugger changes runtime timing |
| An awaited browser operation hangs | NODE_DEBUG="puppeteer:*" and pending protocol error inspection |
Protocol traffic and the initiating call stack | Verbose, potentially sensitive logs |
| Chrome crashes or will not start | dumpio: true, then check installation and environment |
Browser-process output and launch diagnostics | Output can be noisy; platform-specific causes require version checks |
| A visual state or timing sequence needs to be reviewed later | Screenshot or tracing | Saved rendering or a timeline of browser activity | Artifacts take storage and may expose page data |
Or skip the browser setup
If your goal is simply to capture a website rather than debug Puppeteer itself, ScreenshotNeo provides a one-request screenshot API and an MCP server for AI agents. The API can return PNG, JPEG, WebP, or PDF; its optional cleanup accepts cookie and consent banners like a visitor, then removes more than 60 known consent platforms, newsletter popups, and chat widgets. Each cleanup step can be turned off. Only clean shots are billed: bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and responses identify the page verdict and billing status in headers.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsOne cURL request:
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 authentication and available parameters. The MCP server provides take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. Free includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Sign up free for 1,000 screenshots a month, with no card required.
Keep debugging runs useful and safe
- Reproduce the failure with the smallest script and the fewest unrelated browser actions.
- Record the exact URL, last successful operation, timeout or error text, Puppeteer version, browser version, and runtime environment.
- Use one diagnostic channel at a time where possible; a debugger, protocol logging, and tracing together can make timing slower and evidence harder to interpret.
- Remove temporary listeners,
slowMo, debug flags, and traces when the issue is resolved. - Redact credentials, cookies, private URLs, and personal data before sharing logs, screenshots, or trace files.
For timeouts in particular, determine which awaited operation timed out and what condition it was waiting for. Increase a timeout only when the expected operation legitimately needs more time; a longer limit does not fix an unreachable selector, blocked browser download, or stalled protocol command.
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.

