crewAIInc/crewAI · error · ValueError

Cannot convert {type(v).__name__} to file source

Error message

Cannot convert {type(v).__name__} to file source

What it means

Same final-coercion failure as error 137 but in the FileSource union's _coerce validator (core/types.py): the value is not a FileSource instance, str, Path, bytes, or IOBase/BinaryIO. Note this variant accepts IOBase (broader for stdlib streams) but, unlike sources.py's normalizer, does NOT special-case AsyncReadable. So async streams that pass elsewhere fail here. Raised as ValueError during pydantic validation of a FileSource-typed field.

Source

Thrown at lib/crewai-files/src/crewai_files/core/types.py:46

class _FileSourceCoercer:
    """Pydantic-compatible type that coerces various inputs to FileSource."""

    @classmethod
    def _coerce(cls, v: Any) -> FileSource:
        """Convert raw input to appropriate FileSource type."""
        if isinstance(v, (FilePath, FileBytes, FileStream, FileUrl)):
            return v
        if isinstance(v, str):
            if v.startswith(("http://", "https://")):
                return FileUrl(url=v)
            return FilePath(path=Path(v))
        if isinstance(v, Path):
            return FilePath(path=v)
        if isinstance(v, bytes):
            return FileBytes(data=v)
        if isinstance(v, (IOBase, BinaryIO)):
            return FileStream(stream=v)
        raise ValueError(f"Cannot convert {type(v).__name__} to file source")

    @classmethod
    def __get_pydantic_core_schema__(
        cls,
        _source_type: Any,
        _handler: GetCoreSchemaHandler,
    ) -> CoreSchema:
        """Generate Pydantic core schema for FileSource coercion."""
        return core_schema.no_info_plain_validator_function(
            cls._coerce,
            serialization=core_schema.plain_serializer_function_ser_schema(
                lambda v: v,
                info_arg=False,
                return_schema=core_schema.any_schema(),
            ),
        )

View on GitHub (pinned to 754d7323be)

Solutions

  1. Materialize async streams to bytes first (await stream.read()) and pass FileBytes(data=...).
  2. Use one of the concrete classes (FilePath, FileBytes, FileStream, FileUrl) instead of a raw object.
  3. Wrap sync streams in io.BytesIO so they are proper IOBase instances.

Example fix

# before
file = File(source=aiofiles_handle)  # async handle fails FileSource._coerce

# after
data = await aiofiles_handle.read()
file = File(source=FileBytes(data=data))
Defensive patterns

Strategy: type-guard

Validate before calling

from io import IOBase
from pathlib import Path

def filesource_coercible(v) -> bool:
    return isinstance(v, (str, Path, bytes, IOBase))

Type guard

from io import IOBase
from pathlib import Path

def to_filesource(v):
    if isinstance(v, (str, Path, bytes, IOBase)):
        return v  # let pydantic coerce
    if hasattr(v, "read") and hasattr(v, "seek"):
        import io
        return io.BytesIO(v.read())
    raise TypeError(f"cannot coerce {type(v).__name__}")

Try / catch

try:
    File(source=v)
except ValidationError as e:
    if "to file source" in str(e):
        data = await v.read() if hasattr(v, "read") else None
        if data:
            File(source=FileBytes(data=data))

Prevention

When it happens

Trigger: Assigning an int, dict, list, or generator to a field typed FileSource; assigning an aiofiles/async stream object — accepted by _normalize_source (sources.py) via AsyncReadable but rejected here because only IOBase/BinaryIO sync streams coerce; passing a StringO (text IO) where BinaryIO is required is borderline and type-checkers flag it.

Common situations: The same conceptual input working through one entry point (FileSourceInput) but failing through another (FileSource field), confusing users; async uploads routed into sync-typed models.

Related errors


AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15). Data as JSON: /api/errors/8c12bc3f135a6a5a. Report an issue: GitHub.