{"record":{"id":"5fe2fc28ddc4a06f","repo":"SeleniumHQ/selenium","slug":"selenium-server-isn-t-running","errorCode":null,"errorMessage":"Selenium server isn't running","messagePattern":"Selenium server isn't running","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"warning","filePath":"py/selenium/webdriver/remote/server.py","lineNumber":223,"sourceCode":"        host = self.host if self.host is not None else \"localhost\"\n\n        try:\n            with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:\n                sock.connect((host, self.port))\n            raise ConnectionError(f\"Selenium server is already running, or something else is using port {self.port}\")\n        except ConnectionRefusedError:\n            print(\"Starting Selenium server...\")\n            self.process = subprocess.Popen(command, env=self.env)\n            print(f\"Selenium server running as process: {self.process.pid}\")\n            if not self._wait_for_server(timeout=self.startup_timeout):\n                raise TimeoutError(f\"Timed out waiting for Selenium server at {self.status_url}\")\n            print(\"Selenium server is ready\")\n        return self.process\n\n    def stop(self):\n        \"\"\"Stop the server.\"\"\"\n        if self.process is None:\n            raise RuntimeError(\"Selenium server isn't running\")\n        else:\n            if self.process.poll() is None:\n                self.process.terminate()\n                self.process.wait()\n            self.process = None\n            print(\"Selenium server has been terminated\")\n","sourceCodeStart":205,"sourceCodeEnd":230,"githubUrl":"https://github.com/SeleniumHQ/selenium/blob/aa36b38e696a0909e973bdf5e2f9031ffe842c4b/py/selenium/webdriver/remote/server.py#L205-L230","documentation":"Raised by `stop()` when `self.process is None`, i.e. start() was never called (or stop() was already invoked). Since there is no child process to terminate, the method refuses to act and raises. It is a RuntimeError indicating lifecycle misuse.","triggerScenarios":"Calling stop() before start(); calling stop() twice; or calling stop() after start() raised an exception so `process` was never assigned.","commonSituations":"Test teardown running unconditionally in tearDown even when setup failed early; a finally block that runs after a skipped/partial start; calling quit/stop in both an explicit cleanup and an atexit hook.","solutions":["Guard stop() with a check, or only call it when start() succeeded.","Track a started flag and call stop() exactly once in a try/finally.","Catch start() failures so teardown knows whether stop() is valid."],"exampleFix":"# before\nserver = Server()\n# start() failed / wasn't called\nserver.stop()\n\n# after\nserver = Server()\nstarted = False\ntry:\n    server.start(); started = True\nfinally:\n    if started:\n        server.stop()","handlingStrategy":"validation","validationCode":"if server.process is not None:\n    server.stop()","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pair start/stop with a single try/finally and a started flag.","Make teardown idempotent so double-stop or stop-before-start are no-ops."],"tags":["lifecycle","validation","state-error","server-runner"],"backgroundTag":null,"analyzedSha":"aa36b38e696a0909e973bdf5e2f9031ffe842c4b","analyzedAt":"2026-08-14T02:32:32.244Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}