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

  1. Move raw bytes from body= to content=
  2. If the bytes are JSON, pass a dict via body= instead and let the SDK serialize
  3. 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

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


AI-assisted analysis of openai/openai-python@9917c6e28e (2026-08-28). Data as JSON: /api/errors/c8da74868cb0cd7e. Report an issue: GitHub.