{"record":{"id":"bcafb205183d3e3d","repo":"locustio/locust","slug":"no-markov-tasks-defined-in-class-classname-use","errorCode":null,"errorMessage":"No Markov tasks defined in class {classname}. Use the @transition(s) decorators to define some.","messagePattern":"No Markov tasks defined in class (.+?)\\. Use the @transition\\(s\\) decorators to define some\\.","errorType":"validation","errorClass":"NoMarkovTasksError","httpStatus":null,"severity":"error","filePath":"locust/user/markov_taskset.py","lineNumber":153,"sourceCode":"\n\ndef to_weighted_list(transitions: dict):\n    return [name for name in transitions.keys() for _ in range(transitions[name])]\n\n\ndef validate_has_markov_tasks(tasks: list, classname: str):\n    \"\"\"\n    Validates that a MarkovTaskSet has at least one Markov task.\n\n    This function is used internally during MarkovTaskSet validation to ensure\n    that the class has at least one method decorated with @transition or @transitions.\n\n    :param tasks: List of tasks to validate\n    :param classname: Name of the class being validated (for error messages)\n    :raises NoMarkovTasksError: If no Markov tasks are found\n    \"\"\"\n    if not tasks:\n        raise NoMarkovTasksError(\n            f\"No Markov tasks defined in class {classname}. Use the @transition(s) decorators to define some.\"\n        )\n\n\ndef validate_transitions(tasks: list, class_dict: dict, classname: str):\n    \"\"\"\n    Validates that all transitions in Markov tasks point to existing Markov tasks.\n\n    This function checks two conditions for each transition:\n    1. The target task exists in the class\n    2. The target task is also a Markov task (has transitions defined)\n\n    :param tasks: List of Markov tasks to validate\n    :param class_dict: Dictionary containing class attributes and methods\n    :param classname: Name of the class being validated (for error messages)\n    :raises InvalidTransitionError: If a transition points to a non-existent task\n    :raises NonMarkovTaskTransitionError: If a transition points to a task that isn't a Markov task\n    \"\"\"","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/locustio/locust/blob/f391a716e12c2c712e80b5835e877b7933397453/locust/user/markov_taskset.py#L135-L171","documentation":"A MarkovTaskSet subclass must define at least one @task whose transitions are declared via the @transition/@transition_all decorators. validate_has_markov_tasks raises NoMarkovTasksError when the class defines no Markov tasks, because the Markov chain would have no states to traverse.","triggerScenarios":"Defining 'class MyUser(MarkovTaskSet)' with no @task/@transition methods at all, or only plain methods with no transition decorators, then instantiating or validating the class.","commonSituations":"Migrating a regular TaskSet to MarkovTaskSet and forgetting the @transition decorators; leaving a placeholder class empty; typos such as using @task without @transition and assuming tasks alone are enough.","solutions":["Add @task decorated methods and mark transitions between them with @transition(MyUser.task_b, weight=...)","If no Markov behavior is needed, inherit from TaskSet/SequentialTaskSet instead of MarkovTaskSet","Copy a minimal MarkovTaskSet example and add your own states"],"exampleFix":"// before\nclass MyUser(MarkovTaskSet):\n    def browse(self):\n        self.client.get(\"/\")\n// after\nclass MyUser(MarkovTaskSet):\n    @task\n    @transition(MyUser.checkout)\n    def browse(self):\n        self.client.get(\"/\")\n\n    @task\n    def checkout(self):\n        self.client.post(\"/checkout\")","handlingStrategy":"validation","validationCode":"assert any(hasattr(m, \"transitions\") for m in vars(MyUser).values()), \"MarkovTaskSet needs @transition-decorated tasks\"","typeGuard":null,"tryCatchPattern":"try:\n    user = MyUser(env)\nexcept NoMarkovTasksError as e:\n    logging.error(f\"Fix class definition: {e}\")\n    raise","preventionTips":["Always pair @task with @transition in MarkovTaskSet classes","Start from a working MarkovTaskSet example template","Use a plain TaskSet when Markov semantics are not needed"],"tags":["locust","markov-taskset","task-definition","configuration"],"backgroundTag":"no-tasks-defined","analyzedSha":"f391a716e12c2c712e80b5835e877b7933397453","analyzedAt":"2026-08-29T00:36:13.872Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}