Skip to content

fix: strip model from Azure request body after URL construction#2972

Open
alvinttang wants to merge 2 commits intoopenai:mainfrom
alvinttang:fix/azure-strip-model-from-body
Open

fix: strip model from Azure request body after URL construction#2972
alvinttang wants to merge 2 commits intoopenai:mainfrom
alvinttang:fix/azure-strip-model-from-body

Conversation

@alvinttang
Copy link

Summary

  • Fix _build_request in BaseAzureClient to use .pop("model", None) instead of .get("model"), removing the model parameter from the JSON request body after it has been used to construct the /deployments/{model}/... URL path.
  • This prevents Azure OpenAI from rejecting requests when the deployment name differs from the actual model name (e.g., gpt-image-1-5 deployment for model gpt-image-1.5).

Fixes #2892

Root Cause

In src/openai/lib/azure.py, _build_request reads the model field from options.json_data to build the deployment URL but does not remove it. The Azure backend then validates the body's model value against known model names, rejecting deployment names like gpt-image-1-5 that don't match exactly (Azure naming rules prohibit dots in deployment names).

Fix

One-line change: options.json_data.get("model") -> options.json_data.pop("model", None)

This removes model from the body after extracting it for URL construction, which aligns with the Azure OpenAI REST API spec where model selection is done entirely via the URL path for deployment-based endpoints.

Test plan

  • Verify existing tests pass (the change is backwards-compatible since model in the body was always redundant for Azure deployment endpoints)
  • Test with Azure deployment where deployment name differs from model name (e.g., gpt-image-1-5 for gpt-image-1.5)

🤖 Generated with Claude Code

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 openai#2892
@alvinttang alvinttang requested a review from a team as a code owner March 14, 2026 04:03
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7f0456c1dc

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

) -> 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)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid mutating shared json_data when extracting model

Using pop("model", None) here mutates the same json_data mapping that is reused across retries, because BaseClient.request() clones FinalRequestOptions with shallow model_copy() (src/openai/_base_client.py lines 974-987 and src/openai/_compat.py line 122). After the first attempt, retries no longer have model, so _build_request stops prepending /deployments/{model} and sends the retry to a non-deployment URL (e.g. /chat/completions), which can make transient failures unrecoverable for Azure deployment-based calls.

Useful? React with 👍 / 👎.

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) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Azure OpenAI - model parameter in request body causes failures when deployment name differs from model name

1 participant