Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
A Pyppeteer error such as connection unexpectedly closed, WebSocket connection is closed, Websocket connection is lost, or Target closed means that a browser-control operation outlived its connection or page target. It is a symptom, not a single diagnosis. The fastest route to a fix is to record your Python, Pyppeteer, Chromium, and websockets versions, determine whether you launch or attach to Chrome, then isolate browser compatibility, premature shutdown, cancellation, and dependency problems one at a time.
This guide gives a reproducible diagnostic path, safe lifecycle patterns, and recovery steps for crawlers.
What a “connection closed” error actually means
Pyppeteer sends commands to Chromium over a DevTools WebSocket. Your code also works through targets, such as a page. If Chromium exits, the WebSocket disconnects, a page is closed, or a task is cancelled while a command is pending, Pyppeteer can report the same family of failures:
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →connection unexpectedly closedWebSocket connection is closedorWebsocket connection is lostTarget closed
The message alone does not identify whether the browser crashed, your cleanup code ran too early, an attached endpoint disappeared, or a dependency became incompatible. Treat it as a lifecycle or compatibility investigation rather than as a command to retry indefinitely.
#1 Best Overall
- Compatible with Nintendo Switch 2’s new GameChat mode
- Auto-Light Balance: RightLight boosts brightness by up to 50%, reducing shadows so you look your best—compared to previous-generation Logitech webcams (1)
- Privacy with a Slide: The integrated webcam cover makes it easy to get total, reliable privacy when you're not on a video call
- Built-In Mic: The built-in microphone lets others hear you clearly during video calls
- Easy Plug-And-Play: The Brio 101 works with most video calling platforms, including Microsoft Teams, Zoom and Google Meet—no hassle; it just works
Start with a complete runtime record
Before changing code, capture the exact environment that produced the failure. Run these commands in the same virtual environment as the crawler:
python --version
python -m pip show pyppeteer websockets
Record the Chromium or Chrome version as well. If you launch a system binary through executablePath, run that binary’s --version command. Also write down:
- whether the program calls
launch()orconnect(); - the operating system and, if applicable, the container image;
- the complete traceback and browser stderr;
- the URL and operation that was pending when the target disappeared;
- the concurrency level, timeout values, and cancellation path.
This record lets you compare one variable at a time instead of guessing at a “known good” version.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCheck Chromium compatibility first
Pyppeteer’s API documentation is legacy material (the page is labeled Pyppeteer 0.0.25) and says the package works best with its bundled Chromium. It also warns: “There is no guarantee it will work with any other version.” Treat that as a compatibility boundary, not a promise that every bundled revision is suitable for every current Python environment.
Run an A/B test with the bundled browser
- Save the current configuration, including
executablePathif present. - Remove only that override and let
launch()select Pyppeteer’s bundled Chromium. - Run one page and one stable URL with browser diagnostics enabled.
- Compare the result with the system-browser run, recording both browser versions.
If the bundled run is stable and the system-browser run is not, the isolated difference is browser compatibility. Do not “fix” that result by silently changing several package versions at once; choose a tested browser/package combination and document it for deployment.
Rank #2
- Compatible with Nintendo Switch 2’s new GameChat mode
- Crisp HD 720p/30 fps video calls with diagonal 55° field of view and auto light correction. Compatible with popular platforms including Skype and Zoom.
- The built-in noise-reducing mic makes sure your voice comes across clearly up to 1.5 meters away, even if you’re in busy surroundings.
- C270’s RightLight 2 feature adjusts to lighting conditions, producing brighter, contrasted images to help you look good in all your conference calls.
- The adjustable universal clip lets you attach the camera securely to your screen or laptop, or fold the clip and set the webcam on a shelf. You’re always ready for your next video call.
When you attach to an existing browser
With connect(), Pyppeteer does not own the browser process. Verify that the configured browserWSEndpoint is current and reachable at the moment of connection, and that the remote browser is not being restarted by another service. A stale endpoint can look exactly like a browser-side crash. The endpoint and option names come from the older API, so check them against the version installed in your environment.
Find premature browser, page, or context shutdown
Search every code path for browser.close(), browser.disconnect(), page closure, context closure, and cancellation handlers. A common failure is a finally block that runs while another task is still navigating or reading a page.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Give each resource one clear owner
Keep the browser alive for all work that uses it, and close it only after awaited page tasks finish. A simple single-page pattern is:
import asyncio
from pyppeteer import launch
async def fetch_one(url):
browser = await launch({"dumpio": True})
try:
page = await browser.newPage()
await page.goto(url, {
"waitUntil": "networkidle2",
"timeout": 60000,
})
return await page.content()
finally:
await browser.close()
asyncio.run(fetch_one("https://example.com"))
The important property is ownership: the function that creates the browser also keeps it alive until its page operation has completed. In a larger crawler, create one browser at the service level, create pages inside worker tasks, and close the browser only after the worker group has been awaited.
Do not confuse disconnect with close
A close operation terminates the browser that Pyppeteer launched. A disconnect operation ends Pyppeteer’s connection while leaving the external browser running. Choosing the wrong one can either kill work that other tasks still need or leave an orphaned process. Use one policy consistently and document which component owns the process.
Rank #3
- 【Full HD 1080P Webcam】Powered by a 1080p FHD two-MP CMOS, the NexiGo N60 Webcam produces exceptionally sharp and clear videos at resolutions up to 1920 x 1080 with 30fps. The 3.6mm glass lens provides a crisp image at fixed distances and is optimized between 19.6 inches to 13 feet, making it ideal for almost any indoor use.
- 【Wide Compatibility】Works with USB 2.0/3.0, no additional drivers required. Ready to use in approximately one minute or less on any compatible device. Compatible with Mac OS X 10.7 and higher / Windows 7, 8, 10 & 11 / Android 4.0 or higher / Linux 2.6.24 / Chrome OS 29.0.1547 / Ubuntu Version 10.04 or above. Not compatible with XBOX/PS4/PS5.
- 【Built-in Noise-Cancelling Microphone】The built-in noise-canceling microphone reduces ambient noise to enhance the sound quality of your video. Great for Zoom / Facetime / Video Calling / OBS / Twitch / Facebook / YouTube / Conferencing / Gaming / Streaming / Recording / Online School.
- 【USB Webcam with Privacy Protection Cover】The privacy cover blocks the lens when the webcam is not in use. It's perfect to help provide security and peace of mind to anyone, from individuals to large companies. 【Note:】Please contact our support for firmware update if you have noticed any audio delays.
- 【Wide Compatibility】Works with USB 2.0/3.0, no additional drivers required. Ready to use in approximately one minute or less on any compatible device. Compatible with Mac OS X 10.7 and higher / Windows 7, 10 & 11, Pro / Android 4.0 or higher / Linux 2.6.24 / Chrome OS 29.0.1547 / Ubuntu Version 10.04 or above. Not compatible with XBOX/PS4/PS5.
Investigate timeouts and task cancellation
A short asyncio.wait_for around navigation can cancel the coroutine while a DevTools command is still in flight. One historical report made WebSocket loss easier to reproduce this way; it does not prove that every timeout is unsafe.
Separate navigation timeout from worker shutdown
Temporarily remove the outer wait_for, or make it substantially longer, while keeping a page-level navigation timeout. This tells you whether cancellation, rather than page loading, triggers the disconnect.
async def crawl_page(page, url):
await page.goto(url, {
"waitUntil": "domcontentloaded",
"timeout": 60000,
})
return await page.content()
async def run_with_deadline(page, url):
try:
return await asyncio.wait_for(crawl_page(page, url), timeout=90)
except asyncio.TimeoutError:
# Stop using this page after cancellation; let its owner close it.
await page.close()
return None
Never let another task continue using a page after its navigation task has been cancelled. If several workers share one page, cancellation in one worker can corrupt unrelated work; give each concurrent unit its own page or serialize access with a lock.
Test dependency compatibility without guessing
Inspect the installed websockets version along with Pyppeteer and Python. Issue #158, opened in 2018, associated WebSocket loss with an upgrade to websockets 7.0 and speculated about changed connection-termination behavior. That is a historical compatibility report, not a current universal fix or a reason to pin 7.0 blindly.
Use a clean comparison environment
- Create a fresh virtual environment with the same Python major and minor version.
- Install the exact Pyppeteer version used by the crawler and its normal dependency resolution.
- Run the one-page reproduction before adding crawler plugins, proxies, or custom event handlers.
- Change only the dependency under investigation, then repeat the same URL and logging.
If a dependency change alters the result, retain the complete package list and test it on the deployment image. A pin that works locally may fail when Python, Chromium, or the operating system differs.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsRank #4
- 1080P Webcam with Cover for Video Calls - EMEET computer webcam provides design and Optimization for professional video streaming. Realistic 1920 x 1080p video, 5-layer anti-glare lens, providing smooth video. C960 computer camera delivers 1920x1080 video with fixed focus (11.8–118.1 inches), so as to provide a clearer image. C960 USB webcam has a cover and can be removed automatically to meet your needs for privacy. For optimal image performance, use the webcam in a well-lit environment.
- Built-in 2 Omnidirectional Mics - EMEET webcam with microphone for desktop features 2 built-in omnidirectional microphones, picking up your voice to create clear audio for communication. When installing the webcam, select EMEET C960 as the default microphone input device in your computer and video applications and select C960 as the default device in Zoom/Teams and ensure microphone permissions are enabled for proper use. Please note that C960 does not include built-in speakers.
- Automatic Light Adjustment - Automatic exposure adjustment is applied in EMEET HD webcam 1080p so that the streaming webcam can deliver stable image performance. EMEET C960 camera for computer also features color adjustment and exposure optimization to help you look your best. For optimal video quality, it is recommended to use the webcam in normal or well-lit environments and select suitable video settings in your application. Proper lighting helps achieve a clearer and more balanced image.
- Plug-and-Play & Upgraded USB Connectivity - New C960 webcam features both USB Type-A & A-to-C adapter connections for wider compatibility. For stable performance, connect the webcam directly to the computer's main USB port and ensure the device is recognized correctly. If a hub or docking station is used, please ensure it provides sufficient power and stable data transmission, as limited ports may affect performance. 90° wide-angle lens captures more participants without frequent adjustments.
- High Compatibility & Multi Application - C960 webcam for laptop is compatible with Windows 10/11, macOS 10.14+, and Android TV 7.0+. Not supported: Windows Hello, TVs, tablets, or game consoles. It works with Zoom, Teams, Facetime, Google Meet, YouTube and more. Please select C960 webcam as the default camera and microphone device in your application and ensure camera/microphone permissions are enabled, especially on macOS. (Tips: Incompatible with Windows Hello)
Build a minimal reproduction with browser diagnostics
Pyppeteer documents the dumpio launch option and logging controls. Use them to capture Chromium stderr instead of relying only on the final Python exception.
import asyncio
import logging
from pyppeteer import launch
logging.basicConfig(level=logging.DEBUG)
async def main():
browser = await launch({
"dumpio": True,
})
try:
page = await browser.newPage()
await page.goto(
"https://example.com",
{"waitUntil": "load", "timeout": 60000},
)
print((await page.title()).strip())
finally:
await browser.close()
asyncio.run(main())
Use one browser, one page, and a stable URL first. Then restore your real URL, JavaScript handlers, proxy, authentication, and concurrency one change at a time. Preserve the full traceback and stderr for any report; issue reports show that failures can surface during both newPage() and navigation.
Restore crawler concurrency safely
Bound the number of pages
Unlimited page creation increases memory and browser-process pressure and makes ownership errors harder to see. Use a bounded semaphore or worker queue, and wait for every worker before closing the browser.
sem = asyncio.Semaphore(4)
async def worker(browser, url):
async with sem:
page = await browser.newPage()
try:
await page.goto(url, {
"waitUntil": "domcontentloaded",
"timeout": 60000,
})
return await page.content()
finally:
await page.close()
async def crawl(urls):
browser = await launch({"dumpio": True})
try:
tasks = [asyncio.create_task(worker(browser, url)) for url in urls]
return await asyncio.gather(*tasks)
finally:
await browser.close()
Choose the semaphore size from observation, not a magic number. If failures appear only at higher concurrency, reduce the limit while collecting browser stderr and memory data. That narrows whether resource pressure or a race is involved; it does not prove a particular hardware threshold.
Free tools Windows power users keep installed
One-click scans. No signup required.
Keep cancellation ownership explicit
- Cancel workers before closing the browser.
- Await cancelled tasks so their cleanup completes.
- Close each page in its own
finallyblock. - Do not reuse a page after a navigation task has timed out or been cancelled.
- On process shutdown, make one component responsible for browser termination.
Symptom-to-test troubleshooting table
| Observed symptom | Most useful test | Next action |
|---|---|---|
Failure appears only with executablePath |
Run the same script with bundled Chromium | Align the browser and Pyppeteer versions or retain the known-compatible pair |
Target closed during newPage() |
Inspect concurrent close/disconnect paths and browser stderr | Move browser shutdown after all tasks and verify the browser process remains alive |
| WebSocket loss follows a short timeout | Remove the outer asyncio.wait_for and keep a longer page timeout |
Prevent cancelled tasks from sharing the page and close the affected page |
| Only an attached session fails | Reconnect using a freshly obtained WebSocket endpoint | Check remote-browser restarts, endpoint reachability, and ownership |
| Failure changes after dependency installation | Repeat in a clean virtual environment and compare package versions | Test a controlled dependency change; do not apply an old pin without validation |
| Logs contain little browser information | Enable dumpio and debug logging |
Capture stderr, traceback, versions, and the smallest reproducer |
What the available reports do—and do not—prove
Issue #435 (opened April 18, 2023) records Pyppeteer 1.0.2 in headful mode and an error during browser.newPage(). It is an anecdotal report, not proof that headful mode causes closures. Issue #62 (April 11, 2018) describes WebSocket loss in both a container and a laptop and says a short navigation timeout made it easier to reproduce. These reports help identify experiments, but they do not establish a universal timeout, operating-system, or browser-crash rule.
Best Value
- Compatible with Nintendo Switch 2’s new GameChat mode
- HD lighting adjustment and autofocus: The Logitech webcam automatically fine-tunes the lighting, producing bright, razor-sharp images even in low-light settings. This makes it a great webcam for streaming and an ideal web camera for laptop use
- Advanced capture software: Easily create and share video content with this Logitech camera that is suitable for use as a desktop computer camera or a monitor webcam
- Stereo audio with dual mics: Capture natural sound during calls and recorded videos with this 1080p webcam, great as a video conference camera or a computer webcam
- Full HD 1080p video calling and recording at 30 fps. You'll make a strong impression with this PC webcam that features crisp, clearly detailed, and vibrantly colored video
The Pyppeteer repository describes the package as an unofficial port of Puppeteer and points users toward Puppeteer documentation and troubleshooting material. No current Pyppeteer/Python/Chromium/websockets compatibility matrix or universal fix is established here, so retain your version record when escalating a failure.
Or skip the browser setup
If your goal is to obtain page screenshots rather than execute a stateful crawl, ScreenshotNeo returns an image or PDF through one HTTP request. Before capture it accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks, 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. It also offers an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
Use the API documentation for options such as full-page lazy-image loading, CSS-selector element capture, device and retina settings, custom JavaScript or CSS, waits, request blocking, headers, cookies, geolocation, PDF page ranges, signed links, asynchronous webhooks, bulk capture, caching TTLs, and the usage API: ScreenshotNeo API docs.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
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}`);
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. Create a free ScreenshotNeo account to get started.
Frequently Asked Questions
Does headful mode itself cause Pyppeteer connections to close?
No established evidence shows that. Issue #435 reports a headful failure, but it is an individual report; compare headful and headless runs while keeping browser, package, URL, and timing constant.
The Bottom Line
Diagnose the closure as a lifecycle or compatibility failure: compare bundled and system Chromium, verify endpoint ownership, prevent premature close or cancellation, test dependencies in a clean environment, and capture browser stderr from a minimal one-page run.
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.
Recommended Free Tools

