The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →The error Execution context was destroyed, most likely because of a navigation usually means Puppeteer tried to evaluate JavaScript in a page or frame whose document context had just been discarded. The fix is to synchronize your next operation with what the page actually does: wait for navigation when a full navigation is expected, or wait for a result-specific selector when the page updates in place. Register a navigation wait before the click or submit that triggers it, then reacquire elements after the transition.
What the error means
Puppeteer evaluates JavaScript inside an execution context associated with a page or frame. When a document navigates, its old context is disposed; an evaluation still targeting that context can fail before a replacement is ready. Puppeteer’s current CDP implementation tracks context disposal and waits for a context when needed; if the isolated world is disposed before a replacement arrives, it raises Execution context was destroyed. See the Puppeteer IsolatedWorld implementation.
As an Amazon Associate I earn from qualifying purchases.
The message identifies a context-lifecycle race, not by itself a browser crash, a Puppeteer defect, or a problem with your host environment. Use the failing stack-trace operation and the actions immediately before it to find what changed the page or frame.
Free tools Windows power users keep installed
One-click scans. No signup required.
Fix it when an action is expected to navigate
Start waiting for navigation before triggering the click or form submission. Starting the wait first avoids missing a fast navigation event:
#1 Best Overall
await Promise.all([
page.waitForNavigation({ waitUntil: 'domcontentloaded' }),
page.click('a#navigate-away'),
]);
const title = await page.title();
domcontentloaded is a useful choice when the next operation needs the parsed document but not necessarily every resource. Choose a later lifecycle event or a page-specific readiness signal if your next step depends on content that appears later. Do not select networkidle automatically: persistent network requests can keep it from being a useful indication that the page is ready. The important part is to await both the navigation wait and the action, as in the Promise.all pattern described in this Puppeteer error guide.
Fix it when navigation is uncertain or the page updates in place
Some clicks submit data or update a single-page application without replacing the document. In that case, a navigation wait may time out or wait for the wrong event. Wait for a selector that proves the intended result is present:
Rank #2
await page.click('button#submit');
await page.waitForSelector('.success-message');
const message = await page.$eval('.success-message', el => el.textContent);
Choose a selector that distinguishes the completed state from the prior state. A generic heading is sufficient only if it reliably identifies the result for this workflow. For an application with no reliable DOM marker, wait on the application-state signal your code can observe rather than assuming that the click itself means the update has finished.
Handle reloads, redirects, and frame changes safely
After a reload, redirect, history navigation, or frame transition, treat element handles from the old document as stale. Wait for the relevant transition, then query the new document again instead of carrying an old handle across it.
A Puppeteer issue reports a selector query failing after page.reload() on one site, while another site did not reproduce it. The report used Puppeteer 20.7.3, Node 20.3.0, and macOS; it demonstrates site-dependent behavior, not a compatibility guarantee or proof of a universal Puppeteer bug. See Puppeteer issue #10435.
Diagnose the failing sequence
- Find the exact failing call. Determine whether it is a page evaluation, selector query, frame operation, or use of an element handle.
- Check what ran immediately before it. Look for a click, form submit,
page.reload(),goto(), redirect, back/forward action, or frame detachment. - Decide which wait matches the behavior. Use a navigation wait if a full document navigation is expected; use a result-specific selector or application-state signal if the page may update in place.
- Re-query after the transition. Select elements again from the new document instead of reusing handles created in the old context.
- If intermittent, compare environments. Record the exact Node.js and Puppeteer versions from the lockfile and CI image, plus the URL, active frame, action, wait condition, and timeout when the failure occurs.
Troubleshoot recurring or CI-only failures
- The error follows a click or submit: Check whether it starts navigation. If it does, register and await
waitForNavigation()before the action. If it does not, wait for the resulting state instead. - The error follows a reload or redirect: Treat old element handles as belonging to the old document; reacquire them after the new page is ready.
- The wait sometimes times out: Confirm that the selected wait reflects the actual workflow. A navigation wait is inappropriate for an in-place update, and a generic selector may appear before the relevant content is ready.
- It fails only in CI: Compare the actual Node.js and Puppeteer versions and workflow in CI with local versions. Log the URL before and after the action, the failing operation, active frame, navigation or state wait, and timeout. A report of a CI failure also mentions version differences, navigation, forms, waits, missing elements, and timeouts, so it does not establish CI itself as the cause. See Puppeteer issue #12968.
- It appears site-specific: Reduce the sequence to the action and evaluation that fail on that site, then verify whether a redirect, asynchronous update, or frame change intervenes. A single site’s behavior is not enough to diagnose a general Puppeteer regression.
Or skip the browser setup
If your goal is to capture a page rather than automate a browser workflow, ScreenshotNeo offers a screenshot API and MCP server. One GET request returns an image or PDF; the request below saves a WebP screenshot. See the ScreenshotNeo API documentation for request options.
Rank #4
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents. 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.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Frequently Asked Questions
Does this error mean Puppeteer crashed?
No. It indicates that an evaluation encountered a destroyed execution context; inspect the operation and page or frame transition around it.
Should I always wait for navigation after a click?
No. Wait for navigation only when a document navigation is expected; for in-place updates, wait for a signal that confirms the intended result.
Quick Recap
Best Value
- Used Book in Good Condition
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.




