unclecode/crawl4ai · error · NotImplementedError
Browser type {self.browser_type} not supported
Error message
Browser type {self.browser_type} not supported What it means
While building subprocess launch flags (_get_browser_args / managed browser path), BrowserManager supports only 'chromium' (and 'firefox' with its own flag set); any other browser_type string reaches the else branch and raises NotImplementedError. This constrains the managed-browser (CDP subprocess) path — Playwright's own launch API supports more types, but this manager does not.
Source
Thrown at crawl4ai/browser_manager.py:406
]
if self.headless:
flags.append("--headless=new")
# Add viewport flag if specified in config
if self.browser_config.viewport_height and self.browser_config.viewport_width:
flags.append(f"--window-size={self.browser_config.viewport_width},{self.browser_config.viewport_height}")
# merge common launch flags
flags.extend(self.build_browser_flags(self.browser_config))
elif self.browser_type == "firefox":
flags = [
"--remote-debugging-port",
str(self.debugging_port),
"--profile",
self.user_data_dir,
]
if self.headless:
flags.append("--headless")
else:
raise NotImplementedError(f"Browser type {self.browser_type} not supported")
return base + flags
async def cleanup(self):
"""Cleanup browser process and temporary directory"""
# Set shutting_down flag BEFORE any termination actions
self.shutting_down = True
if self.browser_process:
try:
# For builtin browsers that should persist, we should check if it's a detached process
# Only terminate if we have proper control over the process
if not self.browser_process.poll():
# Process is still running
self.browser_process.terminate()
# Wait for process to end gracefully
for _ in range(10): # 10 attempts, 100ms each
if self.browser_process.poll() is not None:
breakView on GitHub (pinned to 7e80152142)
Solutions
- Use browser_type='chromium' (default) or 'firefox' when use_managed_browser=True.
- For webkit or other engines, disable the managed browser: BrowserConfig(use_managed_browser=False) and let Playwright's standard launch handle it.
- Check spelling/casing of browser_type against the supported set.
Example fix
# before BrowserConfig(browser_type='webkit', use_managed_browser=True) # NotImplementedError # after BrowserConfig(browser_type='webkit', use_managed_browser=False)
Defensive patterns
Strategy: validation
Validate before calling
MANAGED_SUPPORTED = {'chromium', 'firefox'}
if cfg.get('use_managed_browser') and cfg['browser_type'] not in MANAGED_SUPPORTED:
raise ValueError(f"managed browser supports only {MANAGED_SUPPORTED}, got {cfg['browser_type']}") Type guard
def supports_managed_browser(browser_type: str) -> bool:
return browser_type in {"chromium", "firefox"} Try / catch
try:
browser_config = BrowserConfig(browser_type=bt, use_managed_browser=True)
except NotImplementedError:
browser_config = BrowserConfig(browser_type=bt, use_managed_browser=False) Prevention
- Validate browser_type against {'chromium','firefox'} whenever use_managed_browser=True.
- Use engine names, not brand names, and keep casing lowercase.
- Cover this branch in config unit tests.
When it happens
Trigger: BrowserConfig(browser_type='webkit') combined with use_managed_browser=True; browser_type='chrome' or 'edge' (wrong identifier); typos like 'Chromium' (case-sensitive in this branch).
Common situations: Assuming any Playwright browser works with the managed CDP mode; porting configs from Playwright where browser_type strings differ; using branded names ('chrome') instead of engine names.
Related errors
- Container not found: ${config.container_selector}
- Timeout after {timeout}ms waiting for selector '{wait_for}'
- [NSTProxy] token and channel_id are required
- [NSTProxy] Invalid protocol: {protocol}
- concurrency must be positive
AI-assisted analysis of unclecode/crawl4ai@7e80152142 (2026-08-14).
Data as JSON: /api/errors/86e614b2e190f221.
Report an issue: GitHub.