crewAIInc / crewAIInc/crewAI

[BUG] Knowledge sources reject file_paths when file_path is passed as None, which also breaks model_validate(model_dump())

Open
#7,609 0 comments 0 reactions 0 assignees View on GitHub

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 (the file_paths validator does see file_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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.