diff --git a/src/crewai/crew.py b/src/crewai/crew.py index 8f973f164..8256c53dc 100644 --- a/src/crewai/crew.py +++ b/src/crewai/crew.py @@ -275,6 +275,18 @@ class Crew(BaseModel): return self + @model_validator(mode="after") + def validate_async_task_cannot_include_async_tasks_in_context(self): + """Validates that if a task is set to be executed asynchronously, it cannot include other asynchronous tasks in its context.""" + for task in self.tasks: + if task.async_execution and task.context: + async_tasks_in_context = [t for t in task.context if t.async_execution] + if async_tasks_in_context: + raise ValueError( + f"Task '{task.description}' is asynchronous and cannot include other asynchronous tasks in its context." + ) + return self + def _setup_from_config(self): assert self.config is not None, "Config should not be None." diff --git a/tests/crew_test.py b/tests/crew_test.py index d0ccb9801..1d28bf0ce 100644 --- a/tests/crew_test.py +++ b/tests/crew_test.py @@ -7,7 +7,6 @@ from unittest.mock import patch import pydantic_core import pytest - from crewai.agent import Agent from crewai.agents.cache import CacheHandler from crewai.crew import Crew @@ -87,6 +86,33 @@ def test_crew_config_conditional_requirement(): ] +def test_async_task_context_validation(): + task1 = Task( + description="Task 1", + async_execution=True, + expected_output="output", + agent=researcher, + ) + task2 = Task( + description="Task 2", + async_execution=True, + expected_output="output", + agent=researcher, + context=[task1], + ) + task3 = Task( + description="Task 3", + expected_output="output", + agent=researcher, + ) + + with pytest.raises( + ValueError, + match="Task 'Task 2' is asynchronous and cannot include other asynchronous tasks in its context.", + ): + Crew(tasks=[task1, task2, task3], agents=[researcher, writer]) + + def test_crew_config_with_wrong_keys(): no_tasks_config = json.dumps( {