From 7f0456c1dc5b87424f3c005feb233b8f41cb6a22 Mon Sep 17 00:00:00 2001 From: Alvin Tang Date: Sat, 14 Mar 2026 12:03:08 +0800 Subject: [PATCH 1/2] fix: strip model from Azure request body after URL construction When using AzureOpenAI, the _build_request method uses the model parameter from the JSON body to construct the deployment URL path, but leaves it in the body. Azure validates this field against actual model names, causing failures when the deployment name differs (e.g. 'gpt-image-1-5' vs 'gpt-image-1.5'). Change .get('model') to .pop('model', None) so the model parameter is removed from the request body after being used for URL routing. Fixes #2892 --- src/openai/lib/azure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openai/lib/azure.py b/src/openai/lib/azure.py index ad64707261..397ec52198 100644 --- a/src/openai/lib/azure.py +++ b/src/openai/lib/azure.py @@ -61,7 +61,7 @@ def _build_request( retries_taken: int = 0, ) -> httpx.Request: if options.url in _deployments_endpoints and is_mapping(options.json_data): - model = options.json_data.get("model") + model = options.json_data.pop("model", None) if model is not None and "/deployments" not in str(self.base_url.path): options.url = f"/deployments/{model}{options.url}" From fdcc5cf780d2101961f80c5207c167b0dde781eb Mon Sep 17 00:00:00 2001 From: Alvin Tang Date: Mon, 16 Mar 2026 21:40:09 +0800 Subject: [PATCH 2/2] fix: avoid mutating shared json_data during Azure deployment URL rewrite Replace `json_data.pop("model")` with `.get()` + dict comprehension so the original mapping is not mutated. This prevents retries from losing the `model` key (and therefore sending requests to the wrong URL) when `BaseClient.request()` reuses a shallow-copied options object. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/openai/lib/azure.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/openai/lib/azure.py b/src/openai/lib/azure.py index 397ec52198..2429083533 100644 --- a/src/openai/lib/azure.py +++ b/src/openai/lib/azure.py @@ -61,9 +61,10 @@ def _build_request( retries_taken: int = 0, ) -> httpx.Request: if options.url in _deployments_endpoints and is_mapping(options.json_data): - model = options.json_data.pop("model", None) + model = options.json_data.get("model") if model is not None and "/deployments" not in str(self.base_url.path): options.url = f"/deployments/{model}{options.url}" + options.json_data = {k: v for k, v in options.json_data.items() if k != "model"} return super()._build_request(options, retries_taken=retries_taken)