SeleniumHQ/selenium · error · AttributeError

module 'selenium.webdriver' has no attribute {name!r}

Error message

module 'selenium.webdriver' has no attribute {name!r}

What it means

Raised as an AttributeError by selenium.webdriver.__getattr__() when a name accessed on the webdriver package is not in the _LAZY_IMPORTS mapping (top-level shortcuts like Chrome, Firefox, Keys) nor in _LAZY_SUBMODULES (subpackages like chrome, common, remote). The package uses PEP 562 lazy loading via __getattr__; any name outside both registries is not a valid attribute and the standard AttributeError is raised with a message naming the missing attribute.

Source

Thrown at py/selenium/webdriver/__init__.py:103

    "safari": "selenium.webdriver.safari",
    "support": "selenium.webdriver.support",
    "webkitgtk": "selenium.webdriver.webkitgtk",
    "wpewebkit": "selenium.webdriver.wpewebkit",
}


def __getattr__(name):
    if name in _LAZY_IMPORTS:
        module_path, attr_name = _LAZY_IMPORTS[name]
        module = importlib.import_module(module_path)
        value = getattr(module, attr_name)
        globals()[name] = value
        return value
    if name in _LAZY_SUBMODULES:
        module = importlib.import_module(_LAZY_SUBMODULES[name])
        globals()[name] = module
        return module
    raise AttributeError(f"module 'selenium.webdriver' has no attribute {name!r}")


def __dir__():
    return sorted(set(__all__) | set(_LAZY_SUBMODULES.keys()))


__all__ = sorted(_LAZY_IMPORTS.keys())

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Check _LAZY_IMPORTS keys in selenium/webdriver/__init__.py for the exact valid top-level names (Chrome, Edge, Firefox, Ie, Safari, Remote, Keys, ActionChains, etc.).
  2. For names not at the top level, import from their full path: e.g. `from selenium.webdriver.common.by import By`.
  3. If the name is a submodule (chrome, common, remote), access it as selenium.webdriver.chrome etc.
  4. Verify the Selenium version — the lazy import set may have changed between versions.

Example fix

# before
from selenium import webdriver
driver = webdriver.Chrom()  # typo, AttributeError

# after
from selenium import webdriver
driver = webdriver.Chrome()  # correct lazy import name
# or for non-top-level names:
from selenium.webdriver.common.by import By
Defensive patterns

Strategy: validation

Validate before calling

import selenium.webdriver as wd
_VALID = set(wd.__dir__())
if name not in _VALID:
    raise AttributeError(f'{name} not in webdriver. Valid: {sorted(_VALID)}')

Try / catch

try:
    cls = getattr(webdriver, name)
except AttributeError as e:
    if 'has no attribute' in str(e):
        # check __dir__() or import from full path
        from selenium.webdriver.common.by import By
    else:
        raise

Prevention

When it happens

Trigger: Accessing selenium.webdriver.SomeName where SomeName is not a registered lazy import (e.g. 'Chrome', 'Firefox', 'Keys', 'ActionChains') or a registered submodule (e.g. 'chrome', 'common', 'remote'). The __getattr__ function is invoked for any attribute not found normally.

Common situations: Misspelling a class name (e.g. webdriver.Chrom instead of webdriver.Chrome); accessing a class that exists but is not exported at the webdriver top level (e.g. webdriver.By should be selenium.webdriver.common.by.By); using a name from an older or newer Selenium version; IDE auto-import suggesting an invalid path.

Related errors


AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14). Data as JSON: /api/errors/c50eebad4709c07e. Report an issue: GitHub.