Regression of #371 — `ResponsesModel.toString()` leaks into Azure deployment URL path via `PrepareRequest.modelNameOrNull()`
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 68/100
Hướng nghiên cứu
Bắt đầu từ PrepareRequest.modelNameOrNull() và theo dõi cách ResponseCreateParams.model() trả về và biểu diễn ResponsesModel trong quá trình xây dựng URL Azure. Chạy mẫu đã được ghim bằng mvn clean compile exec:java để quan sát đường dẫn được tạo; hoàn tất khi phân đoạn deployment sử dụng gpt-5.4 thay vì biểu diễn wrapper của ResponsesModel.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Regression of #371 — ResponsesModel.toString() leaks into Azure deployment URL path via PrepareRequest.modelNameOrNull()
Description
When using the Responses API (client.responses().create(...)) against an Azure OpenAI / Azure AI Foundry endpoint configured with a deployment-based (legacy-style) base URL, the generated request URL contains the toString() representation of the internal ResponsesModel wrapper instead of the plain model/deployment name.
This is the same symptom originally reported in #371 ("Malformed URL for Response API when using Azure OpenAI"), which was fixed in v0.44.2 via #387. It appears the fix did not account for the ResponsesModel union/sealed type that was introduced later (supporting a plain string, a ChatModel enum, or a "Responses-only" model), so the same failure mode has resurfaced through a different path.
Reproduction
AzureOpenAIClient client = OpenAIOkHttpClient.builder()
.baseUrl("https://<resource>.example.azure-api.net/foundry/") // deployment-based / legacy Azure URL mode
.credential(BearerTokenCredential.create(() -> "<token>"))
.build();
ResponseCreateParams params = ResponseCreateParams.builder()
.model("gpt-5.4")
.input("hello")
.build();
client.responses().create(params);
Expected URL
POST https://<resource>.example.azure-api.net/foundry/openai/deployments/gpt-5.4/responses?api-version=2024-10-21
Actual URL
POST https://<resource>.example.azure-api.net/foundry/openai/deployments/ResponsesModel%7Bstring=gpt-5.4%7D/responses?api-version=2024-10-21
URL-decoded, the deployment path segment is literally ResponsesModel{string=gpt-5.4} instead of gpt-5.4. The backend/gateway correctly rejects this with a 404 since no such deployment exists.
Root cause
com.openai.core.PrepareRequest.modelNameOrNull() uses Kotlin reflection to find a method named model on the request params, invokes it, unwraps the result if it's an Optional, and then unconditionally calls .toString() on whatever remains:
internal fun Params.modelNameOrNull(): String? {
val modelName =
try {
this::class.declaredFunctions.find { it.name == "model" }?.call(this)
} catch (_: Exception) {
null
}
return when (modelName) {
is Optional<*> -> modelName.orElse(null)?.toString()
else -> modelName?.toString()
}
}
For ResponseCreateParams, .model() returns Optional<ResponsesModel>. ResponsesModel is a union/sealed wrapper (it can hold a plain String, a ChatModel, or a ResponsesOnlyModel), and its toString() is implemented for debugging/logging purposes:
override fun toString(): String =
if (this.string != null) "ResponsesModel{string=${this.string}}"
else if (this.chat != null) "ResponsesModel{chat=${this.chat}}"
else if (this.only != null) "ResponsesModel{only=${this.only}}"
else "ResponsesModel{_unknown=${this._json}}"
Because modelNameOrNull() calls .toString() instead of resolving the wrapper via its accessors (e.g. checking isString() and calling asString(), or otherwise handling the chat/only variants), the debug-style string leaks directly into the URL path.
This is analogous to the originally-reported #371 symptom and to #492 (a similar "Optional[ ]" leak for the Azure Image Service), suggesting modelNameOrNull()'s generic reflection + toString() approach is fragile whenever a request type's model field is backed by a union/wrapper type rather than a plain String or simple enum.
Sample app
This Java console app reproduces a bug in the OpenAI Java SDK where the ResponsesModel.toString()
representation leaks into Azure deployment URLs instead of using the plain model name.
The app uses a local MockWebServer to capture the actual request URL generated by the SDK
when making a Responses API call against an Azure OpenAI / Azure AI Foundry endpoint configured
with a deployment-based (legacy-style) base URL. It requires no credentials and sends no
actual request to Azure.
This behavior is a regression of openai-java issue #371.
Build and Run
The reproduction is pinned to com.openai:openai-java:4.56.0 in pom.xml.
Pinning the dependency keeps the sample behavior reproducible if a future SDK version changes
the URL handling.
To build and run:
mvn clean compile exec:java
The output shows the SDK-generated request path, making the ResponsesModel leak
visible without manually constructing the URL.
- Ngôn ngữ chính
- Kotlin
- Star
- 1.5k
- Fork
- 265
- Merge trung bình
- 12 giờ 3 phút
- Pull request đã merge (30 ngày)
- 131
Chuẩn bị môi trường
Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của openai/openai-java
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
openai/openai-java#886 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
openai/openai-java#802 · 2 bình luận · 3 reaction ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 74/100
openai/openai-java#973 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 35/100
openai/openai-java#956 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 35/100
openai/openai-java#952 ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của openai/openai-java
Issue tương tự
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
-
enhancement
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
SimonHalvdansson/Harmonic-HN#363 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 90/100
Automattic/pocket-casts-android#6095 ·
Maintainer thường phản hồi trong vòng 1 ngày