-
Notifications
You must be signed in to change notification settings - Fork 147
Description
Bug Description
I'm using the OpenAI Java SDK (openai-java
) version 0.31.0
. When attempting to call the Chat Completions API using the ChatCompletionRequest
, I receive the following error:
com.theokanning.openai.service.OpenAiHttpException: {
"error": {
"message": "Error reading response body: Unknown key: refusal",
"type": "invalid_response_error",
"param": null,
"code": null
}
}
This also sometimes includes annotations
as an unknown key. The problem seems to stem from how the client handles the ChatMessage
roles.
Root Cause (Suspected)
It appears that the Java SDK sends the role
field with value "assistant"
even when it is not explicitly set by the developer, possibly due to an internal Kotlin default value in the ChatMessage
or ChatCompletionMessageParam
class. When this happens, the API interprets the request as an assistant-to-assistant message, and responds with extra metadata fields like refusal
and annotations
— which the current Java SDK does not expect or parse, hence the deserialization failure.
To Reproduce
RestClientResponseException {
OpenAIClient client = OpenAIOkHttpClient.builder().apiKey(apiKey).build();
ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
.addUserMessage(content)
.model(ChatModel.O3_MINI)
.build();
ChatCompletion chatCompletion = client.chat().completions().create(params);
return chatCompletion.choices().get(0).message().content().orElse("");
}
Expected behavior
The client should either:
Properly serialize the role field and not default to "assistant", or
Gracefully handle new fields like refusal or annotations in the API response without throwing an exception.
Workaround
Currently, there's no clean workaround since the SDK does not allow fine-grained control over internal JSON mapping or suppressing unknown fields.
Environment
Java SDK version: 0.31.0
Java version: 17
OS: Windows 11 (but issue is not OS-dependent)
Notes
This may require updates to the data models or deserialization logic to handle newly introduced fields (refusal, annotations) and prevent silent role overrides in the message builder logic.