litellm - 💡(How to fix) Fix [Bug]: Anthropic `/v1/messages` streaming adapter drops the first non-empty text delta when proxying to `/v1/chat/completions` [2 pull requests]

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…

Root Cause

This is especially visible with Claude Code-compatible clients, because they consume Anthropic Messages streaming events strictly.

Fix Action

Fixed

Code Example

client -> LiteLLM /v1/messages -> OpenAI-compatible backend /v1/chat/completions

---

Hi

---

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hi"}}

---

Hi

---

Expected: Hi, how can I help you?
Actual:   , how can I help you?

---

curl -sS -N --http1.1 --no-buffer \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $LITELLM_KEY" \
  -H "anthropic-version: 2023-06-01" \
  "$LITELLM_BASE_URL/v1/messages" \
  -d '{
    "model": "claude-opus-4.7",
    "messages": [
      {
        "role": "user",
        "content": "Hello"
      }
    ],
    "stream": true,
    "max_tokens": 1000
  }'

---

event: message_start
data: {"type":"message_start", ...}

event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":""}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hi"}}
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 using LiteLLM as an Anthropic-compatible proxy, a request sent to /v1/messages with stream: true sometimes loses the first generated token or first non-empty text delta.

This appears to happen on the adapter path where LiteLLM receives an Anthropic Messages API request:

client -> LiteLLM /v1/messages -> OpenAI-compatible backend /v1/chat/completions

The backend itself does not appear to lose the token. When calling the backend endpoint directly, the SSE stream contains the expected first text delta. However, when the same flow is accessed through LiteLLM’s Anthropic /v1/messages streaming adapter, the final client output can start from the second token or miss the leading text.

This is especially visible with Claude Code-compatible clients, because they consume Anthropic Messages streaming events strictly.

Expected behavior

LiteLLM should preserve every non-empty generated text delta from the upstream OpenAI-compatible streaming response.

For example, if the backend generates:

Hi

the Anthropic-compatible stream returned by LiteLLM should include the first non-empty text delta:

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hi"}}

The client should display:

Hi

Actual behavior

The first non-empty text delta appears to be dropped or not forwarded correctly in some cases. The client output may start after the first token or first chunk, even though the upstream backend generated it correctly.

For example:

Expected: Hi, how can I help you?
Actual:   , how can I help you?

or, with other prompts, the response appears to start from the second token/chunk.

Why this looks like a LiteLLM adapter issue

Direct calls to the backend endpoint return a valid streaming response with no missing leading token.

The issue appears only when the request goes through LiteLLM’s Anthropic /v1/messages streaming adapter and is converted to an OpenAI-compatible /v1/chat/completions backend request.

This suggests that the token is generated correctly by the backend, but one of the early streaming chunks is being consumed, skipped, or not re-emitted during Anthropic SSE conversion.

Steps to Reproduce

Request

curl -sS -N --http1.1 --no-buffer \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $LITELLM_KEY" \
  -H "anthropic-version: 2023-06-01" \
  "$LITELLM_BASE_URL/v1/messages" \
  -d '{
    "model": "claude-opus-4.7",
    "messages": [
      {
        "role": "user",
        "content": "Hello"
      }
    ],
    "stream": true,
    "max_tokens": 1000
  }'

Observed SSE shape

The stream begins normally:

event: message_start
data: {"type":"message_start", ...}

event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":""}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hi"}}

However, in the client output, the first non-empty text delta may not be rendered or may appear to have been dropped.

Suspected cause

The issue may be related to the Anthropic streaming adapter logic that handles the initial content_block_start and the first content_block_delta.

A possible failure mode is:

  1. LiteLLM receives the first upstream text chunk from /v1/chat/completions.
  2. LiteLLM starts a new Anthropic content block.
  3. The adapter emits content_block_start.
  4. The same processed text chunk is not re-queued or re-emitted as content_block_delta.
  5. The first non-empty text delta is effectively dropped.

Another possible edge case is that an empty initial text_delta is emitted before the first non-empty text delta, and strict Anthropic clients may handle this differently than expected.

Impact

This breaks compatibility with Claude Code-style clients that expect Anthropic Messages streaming semantics.

The issue is subtle but user-visible, because responses can begin with missing leading characters or missing first tokens. For coding-agent use cases, this can corrupt command output, explanations, code blocks, or structured responses.


What part of LiteLLM is this about?

Proxy

What LiteLLM version are you on ?

v1.89.0

Twitter / LinkedIn details

No response

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…

FAQ

Expected behavior

LiteLLM should preserve every non-empty generated text delta from the upstream OpenAI-compatible streaming response.

For example, if the backend generates:

Hi

the Anthropic-compatible stream returned by LiteLLM should include the first non-empty text delta:

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hi"}}

The client should display:

Hi

Still need to ship something?

×6

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

Back to top recommendations

TRENDING