Compare commits

..

1 Commits

Author SHA1 Message Date
Devin AI
911fb30ef0 fix: reject non-dict values in process_config with clear ValidationError
Fixes #4419. When an invalid type (e.g. a string) was passed for a field
that expects a Pydantic model like BaseAgent, the process_config function
would crash with AttributeError: 'str' object has no attribute 'get'.

Now process_config raises ValueError for non-dict inputs, which Pydantic
wraps into a proper ValidationError with a clear message like:
  'BaseAgent expected a mapping/dictionary, got str'

Co-Authored-By: João <joao@crewai.com>
2026-02-08 22:15:25 +00:00
2 changed files with 56 additions and 0 deletions

View File

@@ -14,7 +14,16 @@ def process_config(
Returns:
The updated values dictionary.
Raises:
ValueError: If values is not a dictionary (e.g. when an invalid type
is passed for a field that expects a Pydantic model).
"""
if not isinstance(values, dict):
raise ValueError(
f"{model_class.__name__} expected a mapping/dictionary, "
f"got {type(values).__name__}"
)
config = values.get("config", {})
if not config:
return values

View File

@@ -1748,3 +1748,50 @@ def test_async_execution_fails():
with pytest.raises(RuntimeError, match="boom!"):
execution = task.execute_async(agent=researcher)
execution.result()
def test_task_with_invalid_agent_string_raises_validation_error():
with pytest.raises(ValidationError) as exc_info:
Task(
description="Test task",
expected_output="Test output",
agent="not_an_agent",
)
assert "BaseAgent expected a mapping/dictionary, got str" in str(exc_info.value)
def test_task_with_invalid_agent_int_raises_validation_error():
with pytest.raises(ValidationError) as exc_info:
Task(
description="Test task",
expected_output="Test output",
agent=123,
)
assert "BaseAgent expected a mapping/dictionary, got int" in str(exc_info.value)
def test_task_with_invalid_agent_list_raises_validation_error():
with pytest.raises(ValidationError) as exc_info:
Task(
description="Test task",
expected_output="Test output",
agent=[1, 2, 3],
)
assert "BaseAgent expected a mapping/dictionary, got list" in str(exc_info.value)
def test_task_with_none_agent_is_valid():
task = Task(
description="Test task",
expected_output="Test output",
agent=None,
)
assert task.agent is None
def test_task_without_agent_is_valid():
task = Task(
description="Test task",
expected_output="Test output",
)
assert task.agent is None