unclecode/crawl4ai · error · ValueError

Invalid browser type. Must be one of: {', '.join(browsers.ke

Error message

Invalid browser type. Must be one of: {', '.join(browsers.keys())}

What it means

ValueError raised in the Playwright-based path-resolution branch of get_browser_executable_path when browser_type.lower() is not a key of the locally built browsers dict ({'chromium','firefox','webkit'}). This check runs after a cached .path file lookup misses, right before querying Playwright's executable_path.

Source

Thrown at crawl4ai/utils.py:672

        raise RuntimeError(f"Unsupported browser type: {browser_type}")

    # Check if a path has already been saved for this browser type
    home_folder = get_home_folder()
    path_file = os.path.join(home_folder, f"{browser_type.lower()}.path")
    if os.path.exists(path_file):
        with open(path_file, "r") as f:
            return f.read()

    from playwright.async_api import async_playwright
    async with async_playwright() as p:
        browsers = {
            'chromium': p.chromium,
            'firefox': p.firefox, 
            'webkit': p.webkit
        }
        
        if browser_type.lower() not in browsers:
            raise ValueError(
                f"Invalid browser type. Must be one of: {', '.join(browsers.keys())}"
            )
            
        # Save the path int the crawl4ai home folder
        home_folder = get_home_folder()
        browser_path = browsers[browser_type.lower()].executable_path
        if not browser_path:
            raise RuntimeError(f"Browser executable not found for type: {browser_type}")
        # Save the path in a text file with browser type name
        with open(os.path.join(home_folder, f"{browser_type.lower()}.path"), "w") as f:
            f.write(browser_path)
        
        return browser_path

def beautify_html(escaped_html):
    """
    Beautifies an escaped HTML string.

View on GitHub (pinned to 7e80152142)

Solutions

  1. Pass one of the canonical Playwright names: 'chromium', 'firefox', 'webkit' (any case).
  2. Map vendor aliases to Playwright names before calling.
  3. Prefer crawl4ai's higher-level setup API (crawl4ai-setup) which handles browser installation and naming for you.

Example fix

# before
path = await get_browser_executable_path("Chrome")  # ValueError: Invalid browser type. Must be one of: chromium, firefox, webkit

# after
path = await get_browser_executable_path("chromium")
Defensive patterns

Strategy: type-guard

Validate before calling

BROWSERS = {"chromium", "firefox", "webkit"}

if browser_type.lower() not in BROWSERS:
    raise ValueError(f"browser_type must be one of {sorted(BROWSERS)}, got {browser_type!r}")
path = await get_browser_executable_path(browser_type)

Type guard

def is_playwright_browser(name: str) -> bool:
    return isinstance(name, str) and name.lower() in {"chromium", "firefox", "webkit"}

Try / catch

try:
    path = await get_browser_executable_path(name)
except ValueError as e:
    if 'Invalid browser type' in str(e):
        name = canonical_browser(name)  # retry with normalized alias
        path = await get_browser_executable_path(name)

Prevention

When it happens

Trigger: Calling the async setup utility with an unrecognized browser type when no cached path file exists for it — the code lowercases the input then requires one of Playwright's three browser names.

Common situations: Same misuse class as the sibling RuntimeError: 'chrome' vs 'chromium', vendor names, or passing a full executable path instead of a browser type. The lowercase handling here means uppercase 'CHROMIUM' works, but 'chrome' still fails.

Related errors


AI-assisted analysis of unclecode/crawl4ai@7e80152142 (2026-08-14). Data as JSON: /api/errors/6812a3b1f0cc6311. Report an issue: GitHub.