dgtlmoon/changedetection.io · error · BrowserConnectError
Error connecting to the browser - Exception '{str(e)}'
Error message
Error connecting to the browser - Exception '{str(e)}' What it means
Catch-all BrowserConnectError wrapping any other exception during the pyppeteer browser websocket connect, exposing the underlying exception string.
Source
Thrown at changedetectionio/content_fetchers/puppeteer.py:303
logger.debug(f"Extra wait set to {extra_wait}s, requested was {n}s.")
from pyppeteer import Pyppeteer
pyppeteer_instance = Pyppeteer()
# Connect directly using the specified browser_ws_endpoint
# @todo timeout
try:
logger.debug(f"[{watch_uuid}] Connecting to browser at {self.browser_connection_url}")
self.browser = await pyppeteer_instance.connect(browserWSEndpoint=self.browser_connection_url,
ignoreHTTPSErrors=True
)
logger.debug(f"[{watch_uuid}] Browser connected successfully")
except websockets.exceptions.InvalidStatusCode as e:
raise BrowserConnectError(msg=f"Error while trying to connect the browser, Code {e.status_code} (check your access, whitelist IP, password etc)")
except websockets.exceptions.InvalidURI:
raise BrowserConnectError(msg=f"Error connecting to the browser, check your browser connection address (should be ws:// or wss://")
except Exception as e:
raise BrowserConnectError(msg=f"Error connecting to the browser - Exception '{str(e)}'")
# more reliable is to just request a new page
try:
logger.debug(f"[{watch_uuid}] Creating new page")
self.page = await self.browser.newPage()
logger.debug(f"[{watch_uuid}] Page created successfully")
except Exception as e:
logger.error(f"[{watch_uuid}] Failed to create new page: {e}")
# Browser is connected but page creation failed - must cleanup browser
try:
await asyncio.wait_for(self.browser.close(), timeout=3.0)
except Exception as cleanup_error:
logger.error(f"[{watch_uuid}] Failed to cleanup browser after page creation failure: {cleanup_error}")
finally:
self.browser = None
raise
# Add console handler to capture console.log from favicon fetcherView on GitHub (pinned to 5d9c7c6da7)
Solutions
- Read the wrapped exception text — it names the real cause
- Confirm the browser service is reachable: curl http://host:port/json/version
- Switch the fetcher to Playwright (better maintained) instead of puppeteer
- Fix DNS/TLS/network issues indicated by the inner message
Defensive patterns
Strategy: fallback
Validate before calling
import socket
from urllib.parse import urlparse
p = urlparse(browser_url)
try:
socket.getaddrinfo(p.hostname, p.port or 80)
except socket.gaierror:
raise ConfigError('browser host unresolvable') Try / catch
try:
fetcher.fetch_page()
except BrowserConnectError as e:
switch_fetcher('playwright') # maintained fallback
retry_check() Prevention
- Prefer the Playwright fetcher; pyppeteer is unmaintained
- Health-check the browser service before check runs
- Pin compatible browser versions in deployment
When it happens
Trigger: Any non-InvalidStatusCode/InvalidURI failure: DNS resolution failure, refused connection, TLS error on wss://, timeouts, or incompatibility between pyppeteer and the browser's DevTools protocol.
Common situations: Browser container down; pyppeteer (unmaintained) vs modern Chrome protocol drift; network egress blocked; wss cert mismatch.
Related errors
- Error while trying to connect the browser, Code {e.status_co
- Error connecting to the browser, check your browser connecti
- EmptyReply
- Non200ErrorCodeReceived
- Content Fetcher > xPath scraper failed. Please report this U
AI-assisted analysis of dgtlmoon/changedetection.io@5d9c7c6da7 (2026-08-27).
Data as JSON: /api/errors/c1c718b20f06d645.
Report an issue: GitHub.