GeezerVison is showing github.com — Json requestBody cannot be optional · Issue #1354 · openapi-generators/openapi-python-client
Json requestBody cannot be optional #1354DescriptionDescribe the bug
Generating an endpoint from an operation where requestBody has required: false (or required is unspecified) and an application/json content, still requires a body, despite it being optional.
Providing a None body with ...sync_detailed(body=None) will result in nil dereference in _kwargs["json"] = body.to_dict().
Providing an 'empty' body such as ...sync_detailed(body=RequestBody()) will result in an empty json object. i.e. {}, which is not desirable.
OpenAPI Spec File
openapi: 3.1.1
info:
title: ""
version: ""
paths:
/request:
post:
operationId: request
requestBody:
required: false
content:
application/json:
schema:
type: object
responses:
"201":
description: ""
Desktop (please complete the following information):
- OS: macOS 15.7.1
- Python version: 3.13.3
- openapi-python-client version: 0.25.1
Additional context
I've described the bug for application/json request bodies, but it may exist for other content types as well.
Similarly, I provided an example using openAPI spec version 3.1.1, but it might be relevant for other versions as well. Activitydbanty commented on Nov 5, 2025 If the body is not required, that enables you to omit the parameter entirely, like sync_detailed().
Passing any value there will try to set that value as the body. None becomes null, classes become objects, etc.
The client also has a special UNSET value it uses as a sentinel to determine when a value hasn't been passed. If you need to, you can import that from types.py and pass it like sync_detailed(body=UNSET).
The preference, though, is to not pass a value at all if it's not required and you don't need it. orelmaliach commented on Nov 5, 2025 Not passing any value results of course in TypeError: sync_detailed() missing 1 required positional argument: 'body'.
And Unset fails when to_dict() is invoked on it in _get_kwargs.
I generated a test client with above yaml. No custom config/templates, and result is same.
(venv) ➜ cat request.py | grep -A5 sync_detailed
def sync_detailed(
*,
client: Union[AuthenticatedClient, Client],
body: RequestBody,
) -> Response[Any]:
"""
Am I missing something?! dbanty commented on Nov 6, 2025
Am I missing something?!
Nope, you're right! The thing that works for every other type of input doesn't work for bodies 😱. dbanty commented on Nov 6, 2025 I whipped up a potential fix in #1357, please give it a try and let me know if it works!
Sorry for accidentally gaslighting you 😅 orelmaliach commented on Nov 6, 2025 Your quick responses and resolution more than make up for it :)
A quick test from my side looks good for both application/json and application/x-www-form-urlencoded content types! added a commit that references this issue on Dec 3, 2025This issue will close once commit 49fa8fc is merged into the 'main' branch.49fa8fc
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|