{"record":{"id":"087b2794a4d089af","repo":"locustio/locust","slug":"environment-runner-already-exists-self-runner","errorCode":null,"errorMessage":"Environment.runner already exists ({self.runner})","messagePattern":"Environment\\.runner already exists \\((.+?)\\)","errorType":"exception","errorClass":"RunnerAlreadyExistsError","httpStatus":null,"severity":"error","filePath":"locust/env.py","lineNumber":123,"sourceCode":"        self.available_user_tasks = available_user_tasks\n        \"\"\"List of the available Tasks per User Classes to pick from in the Task Picker\"\"\"\n        self.dispatcher_class = dispatcher_class\n        \"\"\"A user dispatcher class that decides how users are spawned, default :class:`UsersDispatcher <locust.dispatch.UsersDispatcher>`\"\"\"\n        self.worker_logs: dict[str, list[str]] = {}\n        \"\"\"Captured logs from all connected workers\"\"\"\n\n        self._remove_user_classes_with_weight_zero()\n        self._validate_user_class_name_uniqueness()\n        self._validate_shape_class_instance()\n\n    def _create_runner(\n        self,\n        runner_class: type[RunnerType],\n        *args,\n        **kwargs,\n    ) -> RunnerType:\n        if self.runner is not None:\n            raise RunnerAlreadyExistsError(f\"Environment.runner already exists ({self.runner})\")\n        self.runner = runner_class(self, *args, **kwargs)\n\n        # Attach the runner to the shape class so that the shape class can access user count state\n        if self.shape_class:\n            self.shape_class.runner = self.runner\n\n        return self.runner\n\n    def create_local_runner(self) -> LocalRunner:\n        \"\"\"\n        Create a :class:`LocalRunner <locust.runners.LocalRunner>` instance for this Environment\n        \"\"\"\n        return self._create_runner(LocalRunner)\n\n    def create_master_runner(self, master_bind_host=\"*\", master_bind_port=5557) -> MasterRunner:\n        \"\"\"\n        Create a :class:`MasterRunner <locust.runners.MasterRunner>` instance for this Environment\n","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/locustio/locust/blob/f391a716e12c2c712e80b5835e877b7933397453/locust/env.py#L105-L141","documentation":"Environment allows only one runner per instance. `_create_runner` raises RunnerAlreadyExistsError if `self.runner` is already set before assigning a new runner of the given class (local, master, or worker).","triggerScenarios":"Calling create_local_runner() twice on the same Environment; calling create_local_runner() after create_master_runner(); reusing a cached Environment object across test launches.","commonSituations":"Test harnesses that build one Environment fixture and start multiple runs; scripts that retry runner creation after a failed start without discarding the Environment; framework code that initializes a runner automatically then user code calls create_*_runner again.","solutions":["Create a fresh Environment for each runner you need","Guard with `if environment.runner is None:` before calling create_*_runner","Call `environment.runner.stop()` / discard the old Environment instead of re-creating the runner","In tests, move Environment construction into a pytest fixture with function scope"],"exampleFix":"// before\nenv.create_local_runner()\nenv.create_local_runner()  # raises\n// after\nif env.runner is None:\n    env.create_local_runner()","handlingStrategy":"validation","validationCode":"if env.runner is None:\n    env.create_local_runner()\nelse:\n    env.runner.stop()  # or create a new Environment","typeGuard":"def runner_is_free(env) -> bool:\n    return env.runner is None","tryCatchPattern":"from locust.exception import RunnerAlreadyExistsError\ntry:\n    env.create_local_runner()\nexcept RunnerAlreadyExistsError:\n    env.runner.stop()\n    env.runner = None\n    env.create_local_runner()","preventionTips":["One Environment per run; build fresh instances in test fixtures","Check `env.runner is None` before create_*_runner","Stop and discard runners on teardown"],"tags":["environment","runner","lifecycle"],"backgroundTag":"duplicate-initialization","analyzedSha":"f391a716e12c2c712e80b5835e877b7933397453","analyzedAt":"2026-08-29T00:36:13.872Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}