litellm - ✅(Solved) Fix [Bug]: `/responses` returns `"object": "chat.completion"` for non-OpenAI providers (Bedrock/Anthropic) — Chat Completions → Responses bridge forwards wrong literal [2 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
BerriAI/litellm#26267Fetched 2026-04-23 07:24:14
View on GitHub
Comments
1
Participants
2
Timeline
5
Reactions
5
Assignees
Timeline (top)
labeled ×3assigned ×1commented ×1

Root Cause

Root cause: - litellm/responses/litellm_completion_transformation/transformation.py (line 1651 on main, line 1381 in 1.81.9) constructs ResponsesAPIResponse by forwarding the upstream Chat Completion's object verbatim:

Fix Action

Fix / Workaround

OpenAI native Responses path returns the correct value, so the response shape silently differs across providers, which breaks any downstream consumer that dispatches on object.

PR fix notes

PR #26327: fix(responses): normalize bridged object field

Description (problem / solution / changelog)

Summary

  • Force bridged Chat Completions -> Responses conversion to emit object: \"response\" instead of forwarding provider chat completion object values.
  • Align bridged providers (Bedrock/Anthropic via bridge, etc.) with OpenAI native Responses top-level schema for downstream object-based dispatch.
  • Add a regression assertion in the existing responses bridge transformation test.

Fix #26267

Test plan

  • poetry run pytest tests/test_litellm/responses/litellm_completion_transformation/test_litellm_completion_responses.py::TestLiteLLMCompletionResponsesConfig::test_transform_chat_completion_response_without_reasoning_content -v
<img width="673" height="771" alt="image" src="https://github.com/user-attachments/assets/0926d22d-02aa-459a-ae74-d5680410dfa9" />

Changed files

  • litellm/responses/litellm_completion_transformation/transformation.py (modified, +1/-1)
  • tests/test_litellm/responses/litellm_completion_transformation/test_litellm_completion_responses.py (modified, +1/-0)

PR #26332: fix(responses): hardcode "response" object literal in Chat Completions bridge

Description (problem / solution / changelog)

Relevant issues

Fixes #26267. Confirmed the fix direction in issue comments and @krrish-berri-2's follow-up ("not intentional - we should just map the response api.object").

Pre-Submission checklist

  • I have Added testing in the tests/test_litellm/ directory, Adding at least 1 test is a hard requirement - see details
  • My PR passes all unit tests on make test-unit (Local: 21/21 pass on tests/test_litellm/responses/litellm_completion_transformation/test_litellm_completion_responses.py::TestLiteLLMCompletionResponsesConfig, including the new regression test. CI will confirm the full suite.)
  • 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

CI (LiteLLM team)

CI status guideline:

  • 50-55 passing tests: main is stable with minor issues.
  • 45-49 passing tests: acceptable but needs attention
  • <= 40 passing tests: unstable; be careful with your merges and assess the risk.
  • Branch creation CI run Link:

  • CI run for the last commit Link:

  • Merge / cherry-pick CI run Links:

Screenshots / Proof of Fix

Problem

LiteLLMCompletionResponsesConfig.transform_chat_completion_response_to_responses_api_response forwarded the upstream Chat Completion's object field verbatim. Because this transformation runs only when bridging Chat Completions to the Responses API, the forwarded value was always "chat.completion":

resp = await litellm.aresponses(
    model="bedrock/anthropic.claude-sonnet-4-...",
    input="Tell me a joke",
)
resp.model_dump()["object"]
# Before this PR: "chat.completion"   <- violates the OpenAI Responses spec
# After this PR:  "response"

The OpenAI native Responses path returns the correct value, so the shape silently differed across providers for anything dispatching on object.

Fix

One-line change in transformation.py:1655: replace object=chat_completion_response.object with object="response".

This aligns the non-streaming bridge with the streaming sibling at streaming_iterator.py:370, which already emits "object": "response" in response_created_event_data. The two bridging paths previously disagreed on this one field.

Regression evidence

Stash-bisect against the new test on the current branch HEAD:

  • Without the fix: AssertionError: assert 'chat.completion' == 'response'
  • With the fix: 1 passed in 0.48s

Full TestLiteLLMCompletionResponsesConfig class: 21/21 pass (20 pre-existing + 1 new).

Changes

Files

  • litellm/responses/litellm_completion_transformation/transformation.py (1 line)
  • tests/test_litellm/responses/litellm_completion_transformation/test_litellm_completion_responses.py (+33 lines)

Tests

  • TestLiteLLMCompletionResponsesConfig::test_transform_chat_completion_response_sets_object_to_response: feeds a ModelResponse with object="chat.completion" (the shape the bridge receives from any Chat Completion upstream) through the transform, asserts the returned ResponsesAPIResponse.object == "response".

Changed files

  • litellm/responses/litellm_completion_transformation/transformation.py (modified, +1/-1)
  • tests/test_litellm/responses/litellm_completion_transformation/test_litellm_completion_responses.py (modified, +33/-0)

Code Example

import litellm
# Bedrock / Claude via the Responses API bridge
resp = await litellm.aresponses(
    model="bedrock/anthropic.claude-sonnet-4-...",
    input="Tell me a joke",
)
print(resp.model_dump()["object"])
# Actual:   "chat.completion"
# Expected: "response"

---

// Bedrock / Claude — WRONG
{
  "id": "resp_...",
  "model": "anthropic.claude-sonnet-4-6",
  "object": "chat.completion",   // ← bug
  "output": [ { "type": "message", ... } ],
  ...
}

---

// OpenAI — CORRECT
{
  "id": "resp_...",
  "model": "gpt-5-mini",
  "object": "response",          // ← correct
  "output": [ ... ],
  ...
}

---

responses_api_response: ResponsesAPIResponse = ResponsesAPIResponse(
    id=chat_completion_response.id,
    created_at=chat_completion_response.created,
    model=chat_completion_response.model,
    object=chat_completion_response.object,   # ← always "chat.completion" here
    ...
)

---
RAW_BUFFERClick to expand / collapse

Check for existing issues

  • I have searched the existing issues and checked that my issue is not a duplicate.

What happened?

When calling the Responses API (litellm.aresponses(...)) against any provider that does not have a native Responses implementation and is bridged through LiteLLMCompletionResponsesConfig (Bedrock, Anthropic via Bedrock, etc.), the returned payload's top-level object field is "chat.completion" instead of the spec-required "response".

OpenAI native Responses path returns the correct value, so the response shape silently differs across providers, which breaks any downstream consumer that dispatches on object.

Steps to Reproduce

Reproduction: -

import litellm
# Bedrock / Claude via the Responses API bridge
resp = await litellm.aresponses(
    model="bedrock/anthropic.claude-sonnet-4-...",
    input="Tell me a joke",
)
print(resp.model_dump()["object"])
# Actual:   "chat.completion"
# Expected: "response"

For comparison, the same call against gpt-5-mini correctly returns "object": "response".

Sample payloads (truncated):

// Bedrock / Claude — WRONG
{
  "id": "resp_...",
  "model": "anthropic.claude-sonnet-4-6",
  "object": "chat.completion",   // ← bug
  "output": [ { "type": "message", ... } ],
  ...
}
// OpenAI — CORRECT
{
  "id": "resp_...",
  "model": "gpt-5-mini",
  "object": "response",          // ← correct
  "output": [ ... ],
  ...
}

Root cause: - litellm/responses/litellm_completion_transformation/transformation.py (line 1651 on main, line 1381 in 1.81.9) constructs ResponsesAPIResponse by forwarding the upstream Chat Completion's object verbatim:

responses_api_response: ResponsesAPIResponse = ResponsesAPIResponse(
    id=chat_completion_response.id,
    created_at=chat_completion_response.created,
    model=chat_completion_response.model,
    object=chat_completion_response.object,   # ← always "chat.completion" here
    ...
)

Since this code path only runs when bridging Chat Completions → Responses, the object literal should be hard-coded to "response" (matching the OpenAI spec and the ResponsesAPIResponse schema's intent).

Suggested fix: - Update object=chat_completion_response.object to object="response"

Relevant log output

What part of LiteLLM is this about?

SDK (litellm Python package)

What LiteLLM version are you on ?

1.81.9 version and main branch

Twitter / LinkedIn details

No response

extent analysis

TL;DR

Update the object field assignment in litellm/responses/litellm_completion_transformation/transformation.py to hard-code the value to "response" for bridged providers.

Guidance

  • Verify the issue by checking the object field in the response payload for different providers, ensuring that the OpenAI native path returns the correct value.
  • Update the object assignment in transformation.py to object="response" to match the OpenAI spec and the ResponsesAPIResponse schema.
  • Test the fix by calling the Responses API against bridged providers and verifying that the object field is correctly set to "response".
  • Consider adding a conditional check to ensure the fix only applies to bridged providers, to avoid affecting other implementation paths.

Example

responses_api_response: ResponsesAPIResponse = ResponsesAPIResponse(
    id=chat_completion_response.id,
    created_at=chat_completion_response.created,
    model=chat_completion_response.model,
    object="response",  # Hard-code to "response" for bridged providers
   ...
)

Notes

This fix assumes that the issue is solely caused by the incorrect object field assignment in the transformation.py file. Additional testing and verification may be necessary to ensure the fix does not introduce other issues.

Recommendation

Apply the suggested fix by updating the object field assignment to hard-code the value to "response" for bridged providers, as this aligns with the OpenAI spec and the ResponsesAPIResponse schema.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING