{"record":{"id":"3ddf79072b150e1c","repo":"unclecode/crawl4ai","slug":"unsupported-browser-type-browser-type","errorCode":null,"errorMessage":"Unsupported browser type: {browser_type}","messagePattern":"Unsupported browser type: (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"crawl4ai/utils.py","lineNumber":654,"sourceCode":"    \n    Uses playwright's built-in browser management to get the correct browser executable\n    path regardless of platform. This ensures we're using the same browser version\n    that playwright is tested with.\n    \n    Returns:\n        str: Path to browser executable\n    Raises:\n        RuntimeError: If browser executable cannot be found\n    \"\"\"        \n    browser_types = {\n        \"chromium\": \"chromium\",\n        \"firefox\": \"firefox\",\n        \"webkit\": \"webkit\"\n    }\n    \n    browser_type = browser_types.get(browser_type)\n    if not browser_type:\n        raise RuntimeError(f\"Unsupported browser type: {browser_type}\")\n\n    # Check if a path has already been saved for this browser type\n    home_folder = get_home_folder()\n    path_file = os.path.join(home_folder, f\"{browser_type.lower()}.path\")\n    if os.path.exists(path_file):\n        with open(path_file, \"r\") as f:\n            return f.read()\n\n    from playwright.async_api import async_playwright\n    async with async_playwright() as p:\n        browsers = {\n            'chromium': p.chromium,\n            'firefox': p.firefox, \n            'webkit': p.webkit\n        }\n        \n        if browser_type.lower() not in browsers:\n            raise ValueError(","sourceCodeStart":636,"sourceCodeEnd":672,"githubUrl":"https://github.com/unclecode/crawl4ai/blob/7e801521428ee12509994d39151006f64055ebe3/crawl4ai/utils.py#L636-L672","documentation":"RuntimeError from get_browser_executable_path (utils.py) when browser_type is not one of chromium/firefox/webkit. The dict lookup reassigns browser_type to None for unknown keys and the falsy check raises. Note the message interpolates the already-overwritten variable, so it prints 'Unsupported browser type: None' — the original input is lost.","triggerScenarios":"Passing browser_type values like 'chrome', 'msedge', 'brave', or any casing/typo variant that doesn't exactly match the three Playwright browser keys before the lookup.","commonSituations":"Users naturally writing 'chrome' instead of 'chromium', passing headless-shell or channel names, or forwarding a user-configured browser name unchecked into the setup helper.","solutions":["Use exactly 'chromium', 'firefox', or 'webkit' (Playwright's browser names, not vendor names).","Normalize user input at your boundary: {'chrome': 'chromium', 'msedge': 'chromium'}.get(name.lower(), name.lower()).","Also note this legacy helper predates the dict-based check just below (which lowercases input) — prefer passing already-lowercased canonical names."],"exampleFix":"# before\npath = await get_browser_executable_path(\"chrome\")  # RuntimeError: Unsupported browser type: None\n\n# after\nalias = {\"chrome\": \"chromium\", \"edge\": \"chromium\"}.get(name.lower(), name.lower())\npath = await get_browser_executable_path(\"chromium\")","handlingStrategy":"validation","validationCode":"VALID_BROWSERS = {\"chromium\", \"firefox\", \"webkit\"}\n\ndef canonical_browser(name: str) -> str:\n    aliases = {\"chrome\": \"chromium\", \"edge\": \"chromium\", \"msedge\": \"chromium\", \"brave\": \"chromium\"}\n    n = name.strip().lower()\n    return aliases.get(n, n)\n\n# assert canonical_browser(user_input) in VALID_BROWSERS before calling","typeGuard":"def is_valid_browser_type(name: str) -> bool:\n    return isinstance(name, str) and name.lower() in {\"chromium\", \"firefox\", \"webkit\"}","tryCatchPattern":"try:\n    path = await get_browser_executable_path(browser)\nexcept (RuntimeError, ValueError) as e:\n    if 'browser type' in str(e):\n        raise ValueError(f\"Use chromium/firefox/webkit, got {browser!r}\") from e","preventionTips":["Use Playwright browser names (chromium/firefox/webkit), never vendor names like 'chrome'.","Normalize aliases at your config boundary before passing through.","Note the bug: this message prints 'None' because browser_type is overwritten — check your input, not the message."],"tags":["browser","playwright","validation","configuration"],"backgroundTag":null,"analyzedSha":"7e801521428ee12509994d39151006f64055ebe3","analyzedAt":"2026-08-14T20:46:20.673Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}