{"record":{"id":"83bf561b86dafca1","repo":"locustio/locust","slug":"the-tasks-attribute-can-only-be-set-to-list-or-d","errorCode":null,"errorMessage":"The 'tasks' attribute can only be set to list or dict","messagePattern":"The 'tasks' attribute can only be set to list or dict","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"locust/user/sequential_taskset.py","lineNumber":34,"sourceCode":"\n    def __new__(mcs, classname, bases, class_dict):\n        new_tasks = []\n        for base in bases:\n            # first get tasks from base classes\n            if hasattr(base, \"tasks\") and base.tasks:\n                new_tasks += base.tasks\n        for key, value in class_dict.items():\n            if key == \"tasks\":\n                # we want to insert tasks from the tasks attribute at the point of it's declaration\n                # compared to methods declared with @task\n                if isinstance(value, list):\n                    new_tasks.extend(value)\n                elif isinstance(value, dict):\n                    for task, weight in value.items():\n                        for _ in range(weight):\n                            new_tasks.append(task)\n                else:\n                    raise ValueError(\"The 'tasks' attribute can only be set to list or dict\")\n\n            if \"locust_task_weight\" in dir(value):\n                # method decorated with @task\n                for _ in range(value.locust_task_weight):\n                    new_tasks.append(value)\n\n        class_dict[\"tasks\"] = new_tasks\n        return type.__new__(mcs, classname, bases, class_dict)\n\n\nclass SequentialTaskSet(TaskSet, metaclass=SequentialTaskSetMeta):\n    \"\"\"\n    Class defining a sequence of tasks that a User will execute.\n\n    Works like TaskSet, but task weight is ignored, and all tasks are executed in order. Tasks can\n    either be specified by setting the *tasks* attribute to a list of tasks, or by declaring tasks\n    as methods using the @task decorator. The order of declaration decides the order of execution.\n","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/locustio/locust/blob/f391a716e12c2c712e80b5835e877b7933397453/locust/user/sequential_taskset.py#L16-L52","documentation":"SequentialTaskSet.__new__ expands the 'tasks' attribute into an ordered list. Only lists (and methods decorated with @task) are allowed for sequential execution; other types raise ValueError. Notably, unlike TaskSet, a plain dict of task->weight is rejected here even though the expansion code path handles nested dicts inside lists.","triggerScenarios":"Setting tasks = {TaskA: 3} (a dict) on a SequentialTaskSet subclass, or assigning tasks to a non-list value like a single callable or tuple of unsupported items.","commonSituations":"Copying the dict-based weighted tasks pattern from TaskSet docs into SequentialTaskSet; passing a tuple instead of a list; dynamic task assembly that produces a set or generator.","solutions":["Set 'tasks' to a list; express repetition by duplicating entries, e.g. [TaskA, TaskA, TaskA] instead of {TaskA: 3}","Wrap weighted dicts inside a plain TaskSet instead, or build the list programmatically","Ensure dynamically built tasks are converted with list(...) before assignment"],"exampleFix":"// before\nclass MyFlow(SequentialTaskSet):\n    tasks = {TaskA: 3, TaskB: 1}\n// after\nclass MyFlow(SequentialTaskSet):\n    tasks = [TaskA, TaskA, TaskA, TaskB]","handlingStrategy":"type-guard","validationCode":"tasks = getattr(MyFlow, \"tasks\", [])\nif not isinstance(tasks, list):\n    raise TypeError(\"SequentialTaskSet.tasks must be a list\")","typeGuard":"def has_valid_tasks(cls) -> bool:\n    tasks = getattr(cls, \"tasks\", None)\n    return isinstance(tasks, list) and len(tasks) > 0","tryCatchPattern":"try:\n    flow = MyFlow(user)\nexcept ValueError as e:\n    if \"tasks\" in str(e):\n        logging.error(\"Convert tasks to a list\")\n    raise","preventionTips":["Remember SequentialTaskSet accepts lists only, not weighted dicts","Expand weights manually into repeated list entries","Add a class-level assertion in custom SequentialTaskSet base classes"],"tags":["locust","sequential-taskset","task-definition","type-error"],"backgroundTag":"invalid-tasks-attribute-type","analyzedSha":"f391a716e12c2c712e80b5835e877b7933397453","analyzedAt":"2026-08-29T00:36:13.872Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}