openai/openai-python · warning · DeprecationWarning
Passing raw bytes as `body` is deprecated and will be remove
Error message
Passing raw bytes as `body` is deprecated and will be removed in a future version. Please pass raw bytes via the `content` parameter instead.
What it means
SyncAPIClient.put warns with a DeprecationWarning when the body argument is a raw bytes instance. Raw bytes bodies must now go through the content parameter; body is reserved for JSON-serializable data. The warning is emitted before FinalRequestOptions is constructed and the request sent.
Source
Thrown at src/openai/_base_client.py:1411
)
return self.request(cast_to, opts)
def put(
self,
path: str,
*,
cast_to: Type[ResponseT],
body: Body | None = None,
content: BinaryTypes | None = None,
files: RequestFiles | None = None,
options: RequestOptions = {},
) -> ResponseT:
if body is not None and content is not None:
raise TypeError("Passing both `body` and `content` is not supported")
if files is not None and content is not None:
raise TypeError("Passing both `files` and `content` is not supported")
if isinstance(body, bytes):
warnings.warn(
"Passing raw bytes as `body` is deprecated and will be removed in a future version. "
"Please pass raw bytes via the `content` parameter instead.",
DeprecationWarning,
stacklevel=2,
)
opts = FinalRequestOptions.construct(
method="put", url=path, json_data=body, content=content, files=to_httpx_files(files), **options
)
return self.request(cast_to, opts)
def delete(
self,
path: str,
*,
cast_to: Type[ResponseT],
body: Body | None = None,
content: BinaryTypes | None = None,
options: RequestOptions = {},View on GitHub (pinned to 9917c6e28e)
Solutions
- Move raw bytes from body= to content=
- If the bytes are JSON, pass a dict via body= instead and let the SDK serialize
- Run tests with -W error::DeprecationWarning to catch remaining call sites
Example fix
# before
client.put(url, body=payload_bytes, headers={"Content-Type": "application/octet-stream"})
# after
client.put(url, content=payload_bytes, headers={"Content-Type": "application/octet-stream"}) Defensive patterns
Strategy: type-guard
Validate before calling
if isinstance(body, bytes):
opts = {"content": body}
else:
opts = {"body": body}
client.put(url, **opts) Type guard
def is_raw_bytes(v: object) -> TypeGuard[bytes]:
return isinstance(v, (bytes, bytearray)) Try / catch
with warnings.catch_warnings():
warnings.simplefilter("error", DeprecationWarning)
client.put(url, content=raw) Prevention
- Run tests with -W error::DeprecationWarning to catch these early
- Always use content= for bytes and body= for JSON data
- Grep for 'body=b' and '.encode(' near client calls during upgrades
When it happens
Trigger: Calling client.put(url, body=b"...") — e.g. uploading a pre-serialized JSON string, file bytes, or binary payload via body instead of content.
Common situations: Code written against older SDK versions, or internal helpers that pass bytes bodies for file uploads; warnings may be hidden by default filters and surface only in CI with -W error.
Related errors
- Expected Content-Type response header to be `application/jso
- Multipart request body must be a mapping
- Expected Content-Type response header to be `application/jso
AI-assisted analysis of openai/openai-python@9917c6e28e (2026-08-28).
Data as JSON: /api/errors/c8da74868cb0cd7e.
Report an issue: GitHub.