[BUG] Knowledge sources reject file_paths when file_path is passed as None, which also breaks model_validate(model_dump())
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 58.8k
- Forks
- 8.5k
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 109
Description
Description
A file knowledge source that provides file_paths is rejected as soon as the deprecated file_path field is also passed as an explicit None. Because model_dump() always emits file_path: None, this also breaks pydantic's round-trip contract: a source that constructed fine cannot be re-validated from its own dump.
The guard is registered as a before-field validator on both fields and looks up its sibling through info.data:
# lib/crewai/src/crewai/knowledge/source/base_file_knowledge_source.py:28
@field_validator("file_path", "file_paths", mode="before")
@classmethod
def validate_file_path(cls, v, info):
if (
v is None
and info.data.get(
"file_path" if info.field_name == "file_paths" else "file_paths"
)
is None
):
raise ValueError("Either file_path or file_paths must be provided")
pydantic validates fields in declaration order and info.data only carries the fields validated so far. file_path is declared at :17 and file_paths at :21, so while file_path is being validated the sibling lookup for file_paths is always empty — that half of the guard can never see the field it is supposed to allow for. The asymmetry is visible in the two directions:
file_path=x, file_paths=None→ accepted (thefile_pathsvalidator does seefile_path)file_path=None, file_paths=[x]→ rejected
_process_file_paths() (:89) is the intended behavior: either field on its own is supported, and a file_path that is set simply overrides file_paths after validation.
ExcelKnowledgeSource (excel_knowledge_source.py:31) carries a verbatim copy of the same validator and shows the same failure.
Steps to Reproduce
from crewai.knowledge.source.text_file_knowledge_source import TextFileKnowledgeSource
# knowledge/a.txt exists
src = TextFileKnowledgeSource(file_paths=["a.txt"]) # fine
TextFileKnowledgeSource(file_path=None, file_paths=["a.txt"]) # ValueError
TextFileKnowledgeSource.model_validate(src.model_dump()) # ValueError
Expected behavior
file_paths alone should be accepted whichever way file_path is spelled, and model_validate(model_dump()) should round-trip a source that was itself constructed through the public API.
Evidence
1 validation error for TextFileKnowledgeSource
file_path
Value error, Either file_path or file_paths must be provided [type=value_error, input_value=None, input_type=NoneType]
The same error comes back from model_validate(src.model_dump()), i.e. from a dump of an instance that constructed successfully:
{'file_path': None, 'file_paths': ['a.txt', 'b.txt']}
PDFKnowledgeSource, CSVKnowledgeSource and JSONKnowledgeSource inherit the guard; ExcelKnowledgeSource duplicates it.
Operating System
Windows 11 (also reproduces on Linux — nothing OS specific)
Python Version
3.13
crewAI Version
1.15.22 (main @ 3831e8b)
crewAI Tools Version
Not involved — the defect is in the crewai package.
Virtual Environment
Venv
Possible Solution
Validate the pair where both values are visible instead of per field, e.g. a model_validator(mode="before") that inspects the raw input, so the check no longer depends on which field pydantic happens to validate first:
@model_validator(mode="before")
@classmethod
def validate_file_path(cls, data: Any) -> Any:
if isinstance(data, dict) and ("file_path" in data or "file_paths" in data):
if data.get("file_path") is None and data.get("file_paths") is None:
raise ValueError("Either file_path or file_paths must be provided")
return data
The "file_path" in data or "file_paths" in data condition keeps today's error for a source built with no arguments at all, which _process_file_paths() already reports as file_path/file_paths must be a Path, str, or a list of these types.
Additional context
Found by reading the two field declarations against the validator. Nothing under lib/crewai/tests/ asserts the current message for the file_path=None, file_paths=[...] combination, so the fix is behavior-preserving for every case that works today.
Authored with an AI coding assistant. .github/CONTRIBUTING.md requires the llm-generated label for agent-authored contributions; external contributors cannot apply labels, so maintainers please add it.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with lib/crewai/src/crewai/knowledge/source/base_file_knowledge_source.py and excel_knowledge_source.py, then inspect the knowledge-source tests under lib/crewai/tests/. Reproduce the file_path=None and file_paths combinations, including model_validate(model_dump()). Done means file_paths is accepted in both forms and round-tripping a valid source succeeds without regressing the existing validation behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100