Description
The SDK sends Content-Type: application/json header even when no body is present (e.g., POST requests with no payload). This causes servers with JSON body parsers to fail because an empty string is not valid JSON.
Reproduction
Any POST/PUT/PATCH endpoint that doesn't require a request body:
from opencode_ai import AsyncOpencode
client = AsyncOpencode(base_url="http://localhost:3456")
await client.session.create() # No body parameters
HTTP Request Sent
POST /session HTTP/1.1
Host: localhost:3456
Content-Length: 0
Content-Type: application/json
Accept: application/json
...
Server Response
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
{"name":"UnknownError","data":{"message":"Error: Malformed JSON in request body\n at <anonymous> (../../node_modules/.bun/hono@4.10.7/node_modules/hono/dist/validator/validator.js:21:21)\n at processTicksAndRejections (native:7:39)"}}
The server sees Content-Type: application/json, attempts to parse the body as JSON, but fails because the body is empty.
Expected Behavior
When no body content is provided, the SDK should not send Content-Type: application/json. The header should only be present when there's actual JSON content to parse.
POST /session HTTP/1.1
Host: localhost:3456
Content-Length: 0
Accept: application/json
Root Cause
In _base_client.py, the default_headers property unconditionally includes Content-Type: application/json:
@property
def default_headers(self) -> dict[str, str | Omit]:
return {
"Accept": "application/json",
"Content-Type": "application/json", # Always set
...
}
The _build_request method only removes this header for GET requests:
is_body_allowed = options.method.lower() != "get"
if is_body_allowed:
if isinstance(json_data, bytes):
kwargs["content"] = json_data
else:
kwargs["json"] = json_data if is_given(json_data) else None
kwargs["files"] = files
else:
headers.pop("Content-Type", None) # Only removed for GET
Proposed Fix
Also remove Content-Type when the body is empty for non-GET requests:
if is_body_allowed:
if isinstance(json_data, bytes):
kwargs["content"] = json_data
else:
kwargs["json"] = json_data if is_given(json_data) else None
kwargs["files"] = files
# Remove Content-Type if there's no actual body content
has_body = isinstance(json_data, bytes) or is_given(json_data) or files
if not has_body:
headers.pop("Content-Type", None)
else:
headers.pop("Content-Type", None)
Workaround
Users can manually omit the header:
from opencode_ai import Omit
await client.session.create(extra_headers={"Content-Type": Omit()})
But this shouldn't be necessary for standard API usage.
Environment
- SDK: Stainless-generated Python client
- Python: 3.13.2
- Server: Hono (Node.js) with JSON body validation
Description
The SDK sends
Content-Type: application/jsonheader even when no body is present (e.g., POST requests with no payload). This causes servers with JSON body parsers to fail because an empty string is not valid JSON.Reproduction
Any POST/PUT/PATCH endpoint that doesn't require a request body:
HTTP Request Sent
Server Response
The server sees
Content-Type: application/json, attempts to parse the body as JSON, but fails because the body is empty.Expected Behavior
When no body content is provided, the SDK should not send
Content-Type: application/json. The header should only be present when there's actual JSON content to parse.Root Cause
In
_base_client.py, thedefault_headersproperty unconditionally includesContent-Type: application/json:The
_build_requestmethod only removes this header for GET requests:Proposed Fix
Also remove
Content-Typewhen the body is empty for non-GET requests:Workaround
Users can manually omit the header:
But this shouldn't be necessary for standard API usage.
Environment