Skip to content

fix(azure): build responses input_items url with path before query string - #32270

Merged
mateo-berri merged 2 commits into
litellm_internal_stagingfrom
litellm_fix_azure_input_items_url
Jul 6, 2026
Merged

fix(azure): build responses input_items url with path before query string#32270
mateo-berri merged 2 commits into
litellm_internal_stagingfrom
litellm_fix_azure_input_items_url

Conversation

@mateo-berri

Copy link
Copy Markdown
Contributor

Relevant issues

Found while investigating a customer report on Responses API follow-up calls failing for Azure deployments

Linear ticket

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have added meaningful tests
  • My PR passes all CI/CD checks (e.g., lint, format, unit tests)
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have requested a Greptile review by commenting @greptileai and received a Confidence Score of at least 4/5 before requesting a maintainer review

Screenshots / Proof of Fix

Live proxy (dbless, disable_responses_id_security: true) with a real Azure OpenAI deployment (azure/gpt-4o, api_version 2025-03-01-preview)

curl -s -X POST http://127.0.0.1:53834/v1/responses \
  -H "Authorization: Bearer sk-fix2-local" -H "Content-Type: application/json" \
  -d '{"model":"azure-responses-test","input":"Say hello in five words"}'
# -> {"id":"resp_bGl0ZWxsbT...","status":"completed",...}

curl -s -w "\nHTTP_STATUS:%{http_code}\n" \
  "http://127.0.0.1:53834/v1/responses/<id>/input_items" \
  -H "Authorization: Bearer sk-fix2-local"

Before (staging f628b41), the proxy called a malformed upstream URL where /input_items was appended after the query string, per the proxy debug log

13:26:52 - LiteLLM:DEBUG: transformation.py:303 - list input items url=https://mateo-resource.openai.azure.com/openai/responses/resp_0beef846...?api-version=2025-03-01-preview/input_items

and the client saw Azure's 404 body wrapped in an HTTP 200

{"error":{"code":"404","message":"Resource not found"}}
HTTP_STATUS:200

After the fix, the same two curls hit the correct upstream URL

13:36:10 - LiteLLM:DEBUG: transformation.py:305 - list input items url=https://mateo-resource.openai.azure.com/openai/responses/resp_0301ee69.../input_items?api-version=2025-03-01-preview

and return the real item list

{"object":"list","data":[{"id":"msg_0301ee69...","type":"message","status":"completed","content":[{"type":"input_text","text":"Say hello in five words"}],"role":"user"}],"first_id":"msg_0301ee69...","has_more":false,"last_id":"msg_0301ee69..."}
HTTP_STATUS:200

As a side observation: the upstream 404 body was being passed through as an HTTP 200 to the client, masking the failure. That masking disappears here because the URL is now correct, but the response-status handling for list input items may deserve its own look

Type

🐛 Bug Fix

Changes

GET /v1/responses/{id}/input_items for azure/ models built the upstream URL by string-concatenating "/input_items" onto the output of _construct_url_for_response_id_in_path, which already contains the ?api-version=... query string. Azure therefore received .../responses/{id}?api-version=.../input_items and returned 404 Resource not found

AzureOpenAIResponsesAPIConfig._construct_url_for_response_id_in_path now takes a path_suffix parameter that is inserted into the URL path before the query string is reattached. transform_list_input_items_request passes "/input_items" through it, and transform_cancel_response_api_request (which had duplicated the same parse/unparse logic inline for /cancel) now reuses the shared helper. Get and delete URL building already used the helper and are unchanged. The OpenAI config builds its input_items URL from a query-less api_base, so other providers are unaffected

Regression test added in tests/test_litellm/llms/azure/response/test_azure_transformation.py asserting the exact input_items URL with the path segment before the query string; it fails on the previous concatenation behavior

@mateo-berri

Copy link
Copy Markdown
Contributor Author

@greptileai

@greptile-apps

greptile-apps Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a URL construction bug in AzureOpenAIResponsesAPIConfig where /input_items was appended to the full URL string (including the ?api-version=... query string), causing Azure to receive a malformed path and return a 404 wrapped in HTTP 200.

  • _construct_url_for_response_id_in_path gains an optional path_suffix parameter inserted into the URL path component before urlunparse re-attaches the query string, so the structured path is always …/{id}{suffix}?query rather than …/{id}?query{suffix}.
  • transform_cancel_response_api_request is refactored to reuse the shared helper instead of duplicating the same parse/unparse logic inline, eliminating a near-copy of ~20 lines.
  • A focused regression test is added asserting that the input_items path segment appears before the api-version query parameter.

Confidence Score: 5/5

The change is a well-scoped, correctly implemented bug fix with a targeted regression test; safe to merge.

The root cause (string concatenation after the query string) is fully addressed by injecting the suffix into the structured path component before urlunparse reassembles the URL. The cancel path deduplication removes a parallel implementation that had the same latent bug. The new test exercises the exact failure mode described in the PR. No other providers are affected, and the helper's default empty suffix leaves existing callers (delete, get) unchanged.

No files require special attention.

Important Files Changed

Filename Overview
litellm/llms/azure/responses/transformation.py Adds optional path_suffix to _construct_url_for_response_id_in_path; refactors transform_list_input_items_request and transform_cancel_response_api_request to use the shared helper correctly. Fix is logically sound — suffix is appended to the path tuple component, not the fully-assembled string.
tests/test_litellm/llms/azure/response/test_azure_transformation.py Adds a new unit test test_azure_list_input_items_request_url_path_before_query that uses no real network calls and correctly asserts the exact URL shape after the fix.

Reviews (3): Last reviewed commit: "chore(azure): drop stale inline comment ..." | Re-trigger Greptile

@greptile-apps

greptile-apps Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a URL-construction bug in the Azure Responses API where /input_items was being string-concatenated onto the fully-formed URL (including the ?api-version=... query string), producing a malformed upstream path that Azure responded to with a wrapped 404.

  • _construct_url_for_response_id_in_path gains a path_suffix parameter (default "") that is inserted into the URL path component before the query string is reattached via urlunparse, fixing transform_list_input_items_request.
  • transform_cancel_response_api_request now reuses the same helper (previously it duplicated the parse/unparse logic inline), eliminating the duplication.

Confidence Score: 5/5

The change is a tightly scoped, well-tested URL-construction fix with no side effects on other providers or request paths.

Both affected callers pass statically-known, slash-prefixed suffix strings, the shared helper is covered by existing tests plus the new regression test, and the cancel refactor is a pure de-duplication with identical behavior.

No files require special attention.

Important Files Changed

Filename Overview
litellm/llms/azure/responses/transformation.py Adds path_suffix parameter to _construct_url_for_response_id_in_path so suffixes like /input_items and /cancel are inserted into the URL path before the query string is reattached; also de-duplicates the cancel-URL construction that had the same logic inline.
tests/test_litellm/llms/azure/response/test_azure_transformation.py Adds a regression test asserting that /input_items appears before ?api-version=... in the constructed URL, which fails on the old concatenation approach and passes with the fix.

Comments Outside Diff (1)

  1. litellm/llms/azure/responses/transformation.py, line 228 (link)

    P2 The inline comment on this line is now stale — new_path carries both the response_id and the optional path_suffix (e.g. /input_items, /cancel). A reader looking at the comment alone would not know the suffix is included.

    Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Reviews (2): Last reviewed commit: "fix(azure): build responses input_items ..." | Re-trigger Greptile

@codecov

codecov Bot commented Jul 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@mateo-berri

Copy link
Copy Markdown
Contributor Author

@greptileai

@mateo-berri
mateo-berri enabled auto-merge (squash) July 6, 2026 20:58
@mateo-berri
mateo-berri merged commit e2df153 into litellm_internal_staging Jul 6, 2026
123 checks passed
@mateo-berri
mateo-berri deleted the litellm_fix_azure_input_items_url branch July 6, 2026 21:02
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.

2 participants