Skip to content

fix(openai): handle missing 'id' field in streaming chunks for MiniMax - #23931

Merged
RheagalFire merged 1 commit into
BerriAI:litellm_oss_staging_03_19_2026from
chengyongru:fix/minimax-streaming-keyerror-id
Mar 19, 2026
Merged

fix(openai): handle missing 'id' field in streaming chunks for MiniMax#23931
RheagalFire merged 1 commit into
BerriAI:litellm_oss_staging_03_19_2026from
chengyongru:fix/minimax-streaming-keyerror-id

Conversation

@chengyongru

@chengyongru chengyongru commented Mar 18, 2026

Copy link
Copy Markdown
Contributor
  • Change chunk["id"] to chunk.get("id") for compatibility with MiniMax and other OpenAI-compatible providers
  • ModelResponseStream auto-generates id when None is passed
  • Add regression test test_chunk_parser_without_id_field

Relevant issues

Fixes KeyError: 'id' when using MiniMax m2.5 model with streaming responses

Pre-Submission checklist

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

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

Delays in PR merge?

If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-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:

Type

🐛 Bug Fix
✅ Test

Changes

Problem

When using MiniMax m2.5 model (or other OpenAI-compatible providers), streaming responses may include chunks without an id field. The code at gpt_transformation.py:809 used chunk["id"] which throws KeyError: 'id' when the field is missing.

Solution

  • Changed chunk["id"] to chunk.get("id") in litellm/llms/openai/chat/gpt_transformation.py
  • When id is None, ModelResponseStream automatically generates one via _generate_id()

Files Changed

  • litellm/llms/openai/chat/gpt_transformation.py - Fix KeyError by using safe dict access
  • tests/test_litellm/llms/openai/chat/test_openai_gpt_transformation.py - Add regression test

- Change chunk["id"] to chunk.get("id") for compatibility with MiniMax
- ModelResponseStream auto-generates id when None is passed
- Add regression test test_chunk_parser_without_id_field
@vercel

vercel Bot commented Mar 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
litellm Ready Ready Preview, Comment Mar 18, 2026 2:50am

Request Review

@CLAassistant

CLAassistant commented Mar 18, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@greptile-apps

greptile-apps Bot commented Mar 18, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a KeyError: 'id' crash in the OpenAI streaming handler when an OpenAI-compatible provider (such as MiniMax m2.5) returns streaming chunks that omit the id field. The one-line change from chunk["id"] to chunk.get("id") is the correct minimal fix — ModelResponseStream already calls _generate_id() when id=None is supplied, so no additional changes are needed downstream.

Key changes:

  • litellm/llms/openai/chat/gpt_transformation.py: chunk.get("id") replaces chunk["id"] at line 809, making chunk_parser tolerant of missing id fields from any OpenAI-compatible provider.
  • tests/test_litellm/llms/openai/chat/test_openai_gpt_transformation.py: A new pure-mock regression test test_chunk_parser_without_id_field verifies the fix without making any real network calls, consistent with the test-folder policy.

Confidence Score: 5/5

  • This PR is safe to merge — it is a minimal, well-tested, non-breaking bug fix.
  • The change is a single-line defensive dict access that only affects previously-broken code paths (missing id field). Existing callers that supply id are completely unaffected. The fix is backed by ModelResponseStream's existing _generate_id() fallback, and a focused mock regression test validates the behavior end-to-end with no real network calls.
  • No files require special attention.

Important Files Changed

Filename Overview
litellm/llms/openai/chat/gpt_transformation.py Single-line fix replacing chunk["id"] with chunk.get("id") in chunk_parser; ModelResponseStream already handles None by auto-generating an id via _generate_id().
tests/test_litellm/llms/openai/chat/test_openai_gpt_transformation.py Adds a pure mock regression test test_chunk_parser_without_id_field that constructs a chunk dict without an id field and asserts no KeyError is raised and an id is auto-generated. No real network calls are made.

Sequence Diagram

sequenceDiagram
    participant Provider as MiniMax / OpenAI-compatible Provider
    participant Handler as OpenAIChatCompletionStreamingHandler
    participant MRS as ModelResponseStream

    Provider->>Handler: Streaming chunk (no 'id' field)
    Note over Handler: chunk.get("id") → None<br/>(was chunk["id"] → KeyError)
    Handler->>MRS: ModelResponseStream(id=None, ...)
    Note over MRS: id is None → _generate_id()
    MRS-->>Handler: ModelResponseStream(id="chatcmpl-<generated>", ...)
    Handler-->>Provider: Parsed chunk with auto-generated id
Loading

Last reviewed commit: "fix(openai): handle ..."

@codspeed-hq

codspeed-hq Bot commented Mar 18, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 16 untouched benchmarks


Comparing chengyongru:fix/minimax-streaming-keyerror-id (ce3f24c) with main (cfeafbe)

Open in CodSpeed

@RheagalFire
RheagalFire changed the base branch from main to litellm_oss_staging_03_19_2026 March 19, 2026 07:34
@RheagalFire
RheagalFire merged commit b20c448 into BerriAI:litellm_oss_staging_03_19_2026 Mar 19, 2026
17 of 39 checks passed
@chengyongru
chengyongru deleted the fix/minimax-streaming-keyerror-id branch March 19, 2026 07:43
fzowl pushed a commit to fzowl/litellm that referenced this pull request Jun 24, 2026
BerriAI#23931)

- Change chunk["id"] to chunk.get("id") for compatibility with MiniMax
- ModelResponseStream auto-generates id when None is passed
- Add regression test test_chunk_parser_without_id_field
yassin-berriai added a commit that referenced this pull request Jul 6, 2026
…treams (#32237)

* fix(streaming): surface in-body error payloads on OpenAI-compatible streams

vLLM and sglang return HTTP 200 streams whose SSE body carries the error,
e.g. data: {"error": {"message": "...", "code": 400}}. The OpenAI-compatible
chunk parser had no detection for this shape: since #23931 the payload parsed
into an empty chunk (choices=[]) and the stream ended silently with 200,
losing the provider's error and never attempting configured fallbacks.

Detect the payload in OpenAIChatCompletionStreamingHandler.chunk_parser and
raise OpenAIError with the upstream message and status code. The existing
mid-stream gate then applies: 4xx surface directly to the client, 5xx wrap
into MidStreamFallbackError so the router can run configured fallbacks.

Fixes #25492

* fix(streaming): serialize messageless error payloads as JSON

Address review feedback: an error dict without a message field now
serializes via json.dumps instead of Python dict repr
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.

3 participants