{"record":{"id":"783f987818d8d3a9","repo":"SeleniumHQ/selenium","slug":"a-webdriver-instance-must-be-supplied","errorCode":null,"errorMessage":"A WebDriver instance must be supplied","messagePattern":"A WebDriver instance must be supplied","errorType":"exception","errorClass":"WebDriverException","httpStatus":null,"severity":"error","filePath":"py/selenium/webdriver/support/event_firing_webdriver.py","lineNumber":71,"sourceCode":"        Example:\n            from selenium.webdriver import Firefox\n            from selenium.webdriver.support.events import EventFiringWebDriver, AbstractEventListener\n\n\n            class MyListener(AbstractEventListener):\n                def before_navigate_to(self, url, driver):\n                    print(\"Before navigate to %s\" % url)\n\n                def after_navigate_to(self, url, driver):\n                    print(\"After navigate to %s\" % url)\n\n\n            driver = Firefox()\n            ef_driver = EventFiringWebDriver(driver, MyListener())\n            ef_driver.get(\"http://www.google.co.in/\")\n        \"\"\"\n        if not isinstance(driver, WebDriver):\n            raise WebDriverException(\"A WebDriver instance must be supplied\")\n        if not isinstance(event_listener, AbstractEventListener):\n            raise WebDriverException(\"Event listener must be a subclass of AbstractEventListener\")\n        self._driver = driver\n        # this is valid, but type checkers don't like dynamically assigning to a method\n        self._driver._wrap_value = self._wrap_value  # type: ignore\n        self._listener = event_listener\n\n    @property\n    def wrapped_driver(self) -> WebDriver:\n        \"\"\"Returns the WebDriver instance wrapped by this EventsFiringWebDriver.\"\"\"\n        return self._driver\n\n    def get(self, url: str) -> None:\n        self._dispatch(\"navigate_to\", (url, self._driver), \"get\", (url,))\n\n    def back(self) -> None:\n        self._dispatch(\"navigate_back\", (self._driver,), \"back\", ())\n","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/SeleniumHQ/selenium/blob/aa36b38e696a0909e973bdf5e2f9031ffe842c4b/py/selenium/webdriver/support/event_firing_webdriver.py#L53-L89","documentation":"EventFiringWebDriver.__init__ wraps an existing WebDriver instance; the first argument must be a WebDriver instance (isinstance check). Anything else raises WebDriverException.","triggerScenarios":"EventFiringWebDriver(None, listener), EventFiringWebDriver(WebDriverClass, listener) (passing the class not an instance), or passing a WebElement/Remote connection instead of a driver.","commonSituations":"Forgetting to instantiate the inner driver, or passing arguments in the wrong order (listener first).","solutions":["Instantiate the driver first, then wrap it.","Verify isinstance(driver, WebDriver) before constructing the wrapper."],"exampleFix":"# before\nef = EventFiringWebDriver(Firefox, MyListener())   # class, not instance\n\n# after\nef = EventFiringWebDriver(Firefox(), MyListener())","handlingStrategy":"type-guard","validationCode":"from selenium.webdriver.remote.webdriver import WebDriver\nif not isinstance(driver, WebDriver):\n    raise TypeError(\"first arg must be a WebDriver instance\")","typeGuard":"from selenium.webdriver.remote.webdriver import WebDriver\ndef is_webdriver(v) -> bool:\n    return isinstance(v, WebDriver)","tryCatchPattern":null,"preventionTips":["Construct the inner driver before wrapping it.","Keep argument order: driver first, listener second."],"tags":["events","wrapper","validation"],"backgroundTag":null,"analyzedSha":"aa36b38e696a0909e973bdf5e2f9031ffe842c4b","analyzedAt":"2026-08-14T02:32:32.244Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}