what seems to be happening based on debugging:
given this code:
@task
def first_task(self) -> Task:
return Task(
config=self.tasks_config["first_task"],
)
@task
def second_task(self) -> Task:
return Task(
config=self.tasks_config["second_task"],
context=[self.first_task],
)
the first task runs fine, but the second task fails. this appears to be because
- when a
Task
is defined, part of the underlying flow is to process the task config, which somehow calls this pydantic code: pydantic/pydantic/main.py at bff747748e57c0db384dbd0df886fa623fa3a703 · pydantic/pydantic · GitHub - which calls
process_model_config
(which just callsprocess_config
): https ://github.com/crewAIInc/crewAI/blob/main/src/crewai/task.py#L197 - which gets the
config
attribute of whatever is passed in: https ://github.com/crewAIInc/crewAI/blob/main/src/crewai/utilities/config.py#L19
– crew only lets me put two links in here
so for a task with defined config this works fine, and even for a task with no config it works fine because values get returned i there is no config field found.
however, for some reason i cannot identify, whenever the context
field exists on a Task
, that same 3 step process is subsequently called on the first value of the context array, which is a function
# the Task object
{'description': 'completes task 2.', 'expected_output': 'beep', 'output_json': <class 'task.class'>, 'context': [<bound method task2 of <crewai.project.crew_base.CrewBase(crew) object at 0x105dc3cd0>>]}
# the first value of the context array
<bound method crew.task2 of <crewai.project.crew_base.CrewBase(crew) object at 0x105dc3cd0>>
this results in the error 'function' object has no attribute 'get'
, because the code is trying to get the context
field from a function. bad!
but why?? is the context supposed to be the task rather than a function?? i think it must be that… but then how do we properly express the context as the full task rather than a function?
Edit: Answer
yes, that was it. by changing the context line above to call the function rather than pass it, the failure stops:
context=[self.first_task()],
@matt @Dabnis may want to update the docs to show that the context needs to pass the called function, rather than the function object itself