Skip to content

OpenAI-compatible /v1/chat/completions streaming with stream_options.include_usage returns non-standard SSE (empty choices chunks, empty id/model, trailing {"choices":[],"cost":"0"}) #42918

Closed as not planned

Description

@AbdelftahZowail

Summary

The OpenAI-compatible gateway (opencode.ai/zen/go, /v1/chat/completions) emits non-standard SSE chunks when the client sends stream_options: {"include_usage": true}. This breaks OpenAI-compatible clients that rebuild the streamed response (e.g. LiteLLM crashes with litellm.APIError: Error building chunks for logging/streaming usage calculation).

Without stream_options, the same endpoint streams clean OpenAI-format chunks.

Repro

curl -sN https://opencode.ai/zen/go/v1/chat/completions \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"model":"gpt-5.6-luna","messages":[{"role":"user","content":"say hi"}],"stream":true,"max_tokens":20,"stream_options":{"include_usage":true}}'

Observed SSE (with include_usage)

data: {"id":"gen-...","object":"chat.completion.chunk","created":...,"model":"gpt-5.6-luna","choices":[]}
data: {"id":"gen-...","object":"chat.completion.chunk","created":...,"model":"gpt-5.6-luna","choices":[]}
data: {"id":"","object":"chat.completion.chunk","created":...,"model":"","choices":[]}
data: {"id":"","object":"chat.completion.chunk","created":...,"model":"","choices":[]}
data: {"id":"","object":"chat.completion.chunk","created":...,"model":"","choices":[{"index":0,"delta":{"content":"Hi!"},"finish_reason":null}]}
data: {"id":"","object":"chat.completion.chunk","created":...,"model":"","choices":[]}
data: {"id":"","object":"chat.completion.chunk","created":...,"model":"","choices":[]}
data: {"id":"","object":"chat.completion.chunk","created":...,"model":"","choices":[]}
data: {"id":"gen-...","object":"chat.completion.chunk","created":...,"model":"gpt-5.6-luna","choices":[],"usage":{"prompt_tokens":8,"completion_tokens":6,"total_tokens":14}}
data: {"choices":[],"cost":"0"}

Issues vs OpenAI spec

  1. Empty choices: [] on the first chunks — OpenAI streams always start with a chunk containing choices[0].delta.role; clients use the first chunk to seed the response object.
  2. id and model empty strings on mid-stream chunks — chunks should carry stable id/model.
  3. Trailing data: {"choices":[],"cost":"0"} — not a valid OpenAI chunk (no id/object/created/model); the cost field is non-standard.
  4. Content chunk's delta has no role (fine in the middle, but the first real chunk should carry it).

Impact

Any strict OpenAI-compatible client that accumulates chunks and rebuilds the full response (logging/usage calculation) crashes. LiteLLM (v1.84.0, and still in v1.97.0) raises Error building chunks for logging/streaming usage calculation because it assumes the first chunk with choices has a non-empty array with a delta.role.

Suggestion: only emit chunks with empty choices as the final usage chunk (like OpenAI does), keep id/model populated on every chunk, and drop the cost trailer (or put it inside the usage chunk).

Activity

  1. github-actions commented on Aug 16, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    • OpenAI-compatible cost chunk omits required stream fields #39061: Reports the same non-standard trailing {"choices":[],"cost":"0"} SSE chunk emitted by the Zen OpenAI-compatible endpoint, which lacks required fields (id, object, created, model). Your report extends this with additional symptoms (empty choices on early chunks, missing id/model on mid-stream chunks), but the core trailing cost chunk issue overlaps significantly.
  2. github-actions commented on Oct 16, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions