Regression of #371 — `ResponsesModel.toString()` leaks into Azure deployment URL path via `PrepareRequest.modelNameOrNull()`
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 68/100
Direzione di ricerca
Inizia da PrepareRequest.modelNameOrNull() e traccia il modo in cui ResponseCreateParams.model() restituisce e rappresenta ResponsesModel durante la costruzione dell’URL Azure. Esegui l’esempio fissato con mvn clean compile exec:java per osservare il percorso generato; il lavoro è completato quando il segmento di deployment usa gpt-5.4 invece della rappresentazione wrapper di ResponsesModel.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
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.
- Lingua principale
- Kotlin
- Stelle
- 1.5k
- Fork
- 266
- Merge medio
- 10h 11m
- PR unite (30g)
- 141
Preparare l'ambiente
Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di openai/openai-java
-
HttpRequest.url() logs spaces in path segments as literal plus signsForse già presa @sylvesterkaczmarek l’ha presa 55 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
openai/openai-java#886 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Make diarized transcription duration and task optionalForse già presa @wskr00 l’ha presa 85 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
openai/openai-java#802 · 2 commenti · 3 reazioni ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 3/5 Mezza giornata Idoneità per principianti 42/100
openai/openai-java#1160 ·
I maintainer di solito rispondono entro 1 giorno
-
AsyncStreamResponse can hang when the subscriber executor rejects workForse già presa @sylvesterkaczmarek l’ha presa 38 giorni fa. Aperta
Difficoltà 3/5 1-2 giorni Idoneità per principianti 74/100
openai/openai-java#973 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
openai/openai-java#956 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di openai/openai-java
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 83/100
Kotlin/kotlin-lsp#288 ·
-
afk-ok area:data-quality importer size:S
Difficoltà 2/5 1-3 ore Idoneità per principianti 77/100
enorm-labs/event-junkie#3166 ·
I maintainer di solito rispondono entro 1 giorno
-
bugbane/qf good first issue
Difficoltà 2/5 1-3 ore Idoneità per principianti 64/100
osservatorionessuno/bugbane#173 ·
I maintainer di solito rispondono entro 1 giorno
-
Android: build fails with Android Gradle Plugin 9 (kotlinOptions, lintOptions, proguard-android.txt)Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
capacitor-community/stripe#544 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100