{"record":{"id":"ed248c678a6589fc","repo":"crewAIInc/crewAI","slug":"expected-a-binary-file-like-object-with-read-and","errorCode":null,"errorMessage":"Expected a binary file-like object with read() and seek()","messagePattern":"Expected a binary file-like object with read\\(\\) and seek\\(\\)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"lib/crewai-files/src/crewai_files/core/sources.py","lineNumber":200,"sourceCode":"class _BinaryIOValidator:\n    \"\"\"Pydantic validator for BinaryIO types.\"\"\"\n\n    @classmethod\n    def __get_pydantic_core_schema__(\n        cls, _source_type: Any, _handler: GetCoreSchemaHandler\n    ) -> CoreSchema:\n        return core_schema.no_info_plain_validator_function(\n            cls._validate,\n            serialization=core_schema.plain_serializer_function_ser_schema(\n                lambda x: None, info_arg=False\n            ),\n        )\n\n    @staticmethod\n    def _validate(value: Any) -> BinaryIO:\n        if hasattr(value, \"read\") and hasattr(value, \"seek\"):\n            return cast(BinaryIO, value)\n        raise ValueError(\"Expected a binary file-like object with read() and seek()\")\n\n\nValidatedBinaryIO = Annotated[BinaryIO, _BinaryIOValidator()]\n\n\nclass FilePath(BaseModel):\n    \"\"\"File loaded from a filesystem path.\"\"\"\n\n    path: Path = Field(description=\"Path to the file on the filesystem.\")\n    max_size_bytes: int = Field(\n        default=DEFAULT_MAX_FILE_SIZE_BYTES,\n        exclude=True,\n        description=\"Maximum file size in bytes.\",\n    )\n    _content: bytes | None = PrivateAttr(default=None)\n    _content_type: str = PrivateAttr()\n\n    @model_validator(mode=\"after\")","sourceCodeStart":182,"sourceCodeEnd":218,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai-files/src/crewai_files/core/sources.py#L182-L218","documentation":"Pydantic validator error from the BinaryIO schema: a value passed where a binary file-like object is expected lacks a 'read' or 'seek' attribute. Unlike the async validator, this one IS duck-typed — any object with read() and seek() passes. So hitting it means the value has neither or only one of the two methods, e.g. a text-mode file (which has both, so more commonly: an httpx/starlette response stream with no seek), a generator, or raw bytes.","triggerScenarios":"Passing an httpx response .aread()-style stream, a websocket/generator payload, io.StringIO wrapped oddly, or a custom buffer without seek() to a field typed ValidatedBinaryIO / FileStream(stream=...).","commonSituations":"Streaming downloads handed straight to FileStream without buffering; network stream objects that only support sequential reads; text streams where the developer expected automatic transcoding.","solutions":["Buffer the data first: data = await response.read() then use FileBytes(data=data), or wrap in io.BytesIO which has both read() and seek().","If wrapping a custom class, add seek() (and tell/read) or read the full payload eagerly.","For files, open in binary mode: open(path, 'rb')."],"exampleFix":"# before\nresp = await client.get(url)\nfs = FileStream(stream=resp)  # httpx response: no seek()\n\n# after\nresp = await client.get(url)\nfs = FileBytes(data=resp.content)  # or FileStream(stream=io.BytesIO(resp.content))","handlingStrategy":"type-guard","validationCode":"def is_binary_filelike(v) -> bool:\n    return hasattr(v, \"read\") and hasattr(v, \"seek\")","typeGuard":"import io\n\ndef as_binary(v) -> io.BytesIO:\n    if isinstance(v, (bytes, bytearray)):\n        return io.BytesIO(v)\n    if hasattr(v, \"read\") and hasattr(v, \"seek\"):\n        return v\n    raise TypeError(f\"{type(v).__name__} is not a binary file-like object\")","tryCatchPattern":"try:\n    FileStream(stream=obj)\nexcept ValidationError as e:\n    if \"binary file-like\" in str(e):\n        FileStream(stream=io.BytesIO(obj.read()))  # only if read() exists","preventionTips":["Always buffer network streams with io.BytesIO before wrapping.","Open local files in 'rb' mode."],"tags":["pydantic","validation","file-sources","io"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}