{"record":{"id":"aed2a055773cf669","repo":"openai/openai-python","slug":"could-not-read-bytes-from-data-received-type-b","errorCode":null,"errorMessage":"Could not read bytes from {data}; Received {type(binary)}","messagePattern":"Could not read bytes from (.+?); Received (.+?)","errorType":"validation","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/openai/_utils/_transform.py","lineNumber":256,"sourceCode":"        if format_ == \"iso8601\":\n            return data.isoformat()\n\n        if format_ == \"custom\" and format_template is not None:\n            return data.strftime(format_template)\n\n    if format_ == \"base64\" and is_base64_file_input(data):\n        binary: str | bytes | None = None\n\n        if isinstance(data, pathlib.Path):\n            binary = data.read_bytes()\n        elif isinstance(data, io.IOBase):\n            binary = data.read()\n\n            if isinstance(binary, str):  # type: ignore[unreachable]\n                binary = binary.encode()\n\n        if not isinstance(binary, bytes):\n            raise RuntimeError(f\"Could not read bytes from {data}; Received {type(binary)}\")\n\n        return base64.b64encode(binary).decode(\"ascii\")\n\n    return data\n\n\ndef _transform_typeddict(\n    data: Mapping[str, object],\n    expected_type: type,\n) -> Mapping[str, object]:\n    result: dict[str, object] = {}\n    annotations = get_type_hints(expected_type, include_extras=True)\n    for key, value in data.items():\n        if not is_given(value):\n            # we don't need to include omitted values here as they'll\n            # be stripped out before the request is sent anyway\n            continue\n","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/openai/openai-python/blob/9917c6e28e66e90e1227b3d223c06a8c5441515a/src/openai/_utils/_transform.py#L238-L274","documentation":"When a request body field is typed as a file/upload, the SDK calls .read() on the object and base64-encodes the result for JSON transport. This RuntimeError means the object's read() returned something that is neither bytes nor a str (e.g. a memoryview, bytearray consumed incorrectly, or a custom file-like object returning a generator). The sync transform could not produce bytes to encode, so serialization of the request body fails before sending.","triggerScenarios":"Passing a custom file-like object whose read() returns a non-bytes value; passing a SpooledTemporaryFile wrapper or object wrapping bytes in memoryview; constructing models locally with an improper upload object and then serializing them.","commonSituations":"Custom IO abstractions (e.g. adapters around cloud storage streams) not returning bytes; wrapping files in classes that return the underlying buffer object; upgrading SDK versions where upload handling moved to the transform layer.","solutions":["Ensure the object passed for the file field has read() returning bytes (encode str results)","Wrap custom streams: read = lambda *a: raw.read() or return bytes(memoryview_chunk) from read()","Pass raw bytes or a real file object opened in binary mode ('rb')","Add a unit test asserting your upload object's read() returns bytes"],"exampleFix":"# before\nclass WeirdFile:\n    def read(self): return memoryview(b\"data\")\nclient.models.create(file=WeirdFile())\n\n# after\nclass BytesFile:\n    def read(self, *a): return b\"data\"\nclient.models.create(file=BytesFile())","handlingStrategy":"type-guard","validationCode":"data = f.read() if hasattr(f, \"read\") else f\nassert isinstance(data, (bytes, bytearray)), type(data)","typeGuard":"def is_bytes_readable(obj: object) -> bool:\n    return isinstance(obj, (bytes, bytearray)) or (hasattr(obj, \"read\") and isinstance(getattr(obj, \"read\")(), (bytes, type(None))))","tryCatchPattern":"try:\n    client.models.create(file=f)\nexcept RuntimeError as e:\n    raise ValueError(\"file must read() bytes\") from e","preventionTips":["Open files in binary mode","Keep custom read() returning bytes","Unit test adapters' read() return type"],"tags":["runtimeerror","file-upload","serialization","base64"],"backgroundTag":"file-upload-serialization-failed","analyzedSha":"9917c6e28e66e90e1227b3d223c06a8c5441515a","analyzedAt":"2026-08-28T11:46:34.183Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}