BerriAI/litellm · error · ValueError

Chunk does not start with 'data:': {chunk}

Error message

Chunk does not start with 'data:': {chunk}

What it means

chunk_creator requires every chunk to start with the literal 'data:' prefix (the SSE event-field format OCI uses). A chunk lacking that prefix — e.g. a comment line ':ping', an 'event:' line, a blank line, or leading whitespace — raises ValueError because the parser does not attempt generic SSE framing.

Source

Thrown at litellm/llms/oci/chat/transformation.py:750

            make_call=make_call,
            _response_headers=_response_headers,
        )
        # Tracks whether any prior Cohere chunk in this stream has emitted
        # tool calls. The Cohere handler uses this to decide whether the
        # terminal consolidation chunk's tool calls are duplicates (suppress)
        # or the only copy of the tool calls (pass through).
        self._cohere_tool_calls_emitted = False
        # Analogous flag for text content. Lets the Cohere handler distinguish
        # the common case (prior deltas already streamed the text, so the
        # terminal chunk's text is a duplicate to suppress) from the degenerate
        # single-event case (terminal chunk carries the only copy of the text).
        self._cohere_text_emitted = False

    def chunk_creator(self, chunk: Any) -> ModelResponseStream:
        if not isinstance(chunk, str):
            raise ValueError(f"Chunk is not a string: {chunk}")
        if not chunk.startswith("data:"):
            raise ValueError(f"Chunk does not start with 'data:': {chunk}")
        try:
            dict_chunk: Final = json.loads(chunk[5:])
        except json.JSONDecodeError as e:
            raise OCIError(
                status_code=500,
                message=f"Chunk cannot be parsed as JSON: {e}",
            )

        if dict_chunk.get("apiFormat") == "COHERE":
            result: Final = handle_cohere_stream_chunk(
                dict_chunk,
                prior_tool_calls_emitted=self._cohere_tool_calls_emitted,
                prior_text_emitted=self._cohere_text_emitted,
            )
            if not self._cohere_tool_calls_emitted:
                for choice in result.choices:
                    if getattr(choice.delta, "tool_calls", None) is not None:
                        self._cohere_tool_calls_emitted = True

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Ensure no intermediary rewrites the SSE stream (disable response buffering on gateways, use passthrough proxies).
  2. If iterating manually, filter to lines starting with 'data:' before calling chunk_creator.
  3. Re-run against the OCI endpoint directly to confirm the raw stream framing.
  4. Check for litellm updates if the SSE line-splitting logic changed.

Example fix

# before
for chunk in wrapper.completion_stream:
    model_chunk = handler.chunk_creator(chunk)  # blows up on ': ping'

# after
for chunk in wrapper.completion_stream:
    if not isinstance(chunk, str) or not chunk.startswith("data:"):
        continue
    model_chunk = handler.chunk_creator(chunk)
Defensive patterns

Strategy: validation

Validate before calling

chunk = chunk if isinstance(chunk, str) else ""
if not chunk.startswith("data:"):
    continue  # skip comments/events/blank lines

Type guard

def is_data_event(line: object) -> bool:
    return isinstance(line, str) and line.startswith("data:")

Try / catch

try:
    model_chunk = handler.chunk_creator(chunk)
except ValueError as e:
    if "does not start with 'data:'" in str(e):
        continue  # tolerate non-data SSE lines
    raise

Prevention

When it happens

Trigger: The stream yields lines like 'event: message', ':keep-alive', or an empty string; typically from a nonstandard intermediary that alters SSE framing, or from manual iteration that splits on the wrong boundary and passes partial/garbled lines into chunk_creator.

Common situations: Corporate proxies or API gateways injecting keep-alive comments; misconfigured buffering that merges or truncates SSE lines; test harnesses yielding raw JSON without the 'data:' prefix. Normal direct-to-OCI streaming never produces these lines.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/447feb6423256b83. Report an issue: GitHub.