Repository: locustio/locust
Issue category: Bug Report

Issue:
master crash with different version worker
### Prerequisites

- [X] I am using [the latest version of Locust](https://github.com/locustio/locust/releases/)
- [X] I am reporting a bug, not asking a question

### Description

I ran distributed locust with master node locust version 2.32.2 and some worker node locust version 2.25.0 (python3.8 default version).
The master node crash with the following message
```
➜  load-test locust -f locust.py --master
[2024-11-09 14:41:07,519] nasa33/INFO/locust.main: Starting Locust 2.32.2
[2024-11-09 14:41:07,524] nasa33/INFO/locust.main: Starting web interface at http://0.0.0.0:8089
Traceback (most recent call last):
  File "src/gevent/greenlet.py", line 906, in gevent._gevent_cgreenlet.Greenlet.run
  File "/home/uniform64/.local/lib/python3.10/site-packages/locust/runners.py", line 1030, in client_listener
    if msg.data["version"][0:4] == __version__[0:4]:
TypeError: 'NoneType' object is not subscriptable
2024-11-09T06:41:13Z <Greenlet at 0x7f254a980cc0: <bound method MasterRunner.client_listener of <locust.runners.MasterRunner object at 0x7f254a963100>>> failed with TypeError

[2024-11-09 14:41:13,652] nasa33/CRITICAL/locust.runners: Unhandled exception in greenlet: <Greenlet at 0x7f254a980cc0: <bound method MasterRunner.client_listener of <locust.runners.MasterRunner object at 0x7f254a963100>>>
Traceback (most recent call last):
  File "src/gevent/greenlet.py", line 906, in gevent._gevent_cgreenlet.Greenlet.run
  File "/home/uniform64/.local/lib/python3.10/site-packages/locust/runners.py", line 1030, in client_listener
    if msg.data["version"][0:4] == __version__[0:4]:
TypeError: 'NoneType' object is not subscriptable
```
when I use the following command on worker node.
```
~/.local/bin/locust -f - --worker --master-host 172.16.0.33 --processes -1
```

### Command line

locust -f locust.py --master

### Locustfile contents

```python3
import random
import string
from locust import HttpUser, task


def generate_random_string(length):
    return "".join(random.choices(string.ascii_lowercase+string.digits,
                                  k=length))


def generate_random_bytes(length):
    return random.randbytes(length)


class SimpleClient(HttpUser):
    @task
    def upload(self):
        # random generate a index and some data (both string)
        index = generate_random_string(random.randint(10, 20))
        data = generate_random_bytes(random.randint(100, 200))
        self.client.post("/upload", headers={"Index": index}, data=data)
```


### Python version

3.10

### Locust version

2.32.2

### Operating system

ubuntu22.04


Hints:

Patch:
diff --git a/locust/runners.py b/locust/runners.py
index 9552d519c7..a4165cfa40 100644
--- a/locust/runners.py
+++ b/locust/runners.py
@@ -1025,7 +1025,9 @@ def client_listener(self) -> NoReturn:
                 # if abs(time() - msg.data["time"]) > 5.0:
                 #    warnings.warn("The worker node's clock seem to be out of sync. For the statistics to be correct the different locust servers need to have synchronized clocks.")
             elif msg.type == "locustfile":
-                if msg.data["version"][0:4] == __version__[0:4]:
+                if not msg.data["version"]:
+                    logger.error("A very old worker version requested locustfile. This probably won't work.")
+                elif msg.data["version"][0:4] == __version__[0:4]:
                     logger.debug(
                         f"A worker ({msg.node_id}) running a different patch version ({msg.data['version']}) connected, master version is {__version__}"
                     )


Test patch: