- Notifications
You must be signed in to change notification settings - Fork 4.5k
Description
Description
The OpenAI Python SDK's streaming implementation throws a JSONDecodeError when encountering SSE (Server-Sent Events) events that contain only meta-fields (such as retry, id, or event) but no data field.
Error
File"openai/_streaming.py", line82, in__stream__data=sse.json() File"openai/_streaming.py", line259, injsonreturnjson.loads(self.data) json.decoder.JSONDecodeError: Expectingvalue: line1column1 (char0)Root Cause
Per the SSE specification (WHATWG HTML § 9.2), meta-only events are valid. For example:
retry: 3000 data:{"id":"msg_123",...} The SDK's SSE decoder correctly parses these events, setting the retry field but leaving data empty (empty string). However, Stream.__stream__() and AsyncStream.__stream__() attempt to call .json() on all events, including those with empty data, leading to the error.
Reproduction
This occurs when streaming from SSE sources that send retry directives or other meta-only events. Example:
fromopenaiimportOpenAIclient=OpenAI( api_key="test", base_url="http://gateway-that-sends-retry"# Any gateway/proxy that includes SSE retry ) # This will fail with JSONDecodeError if the stream includes retry directivesstream=client.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": "Hello"}], stream=True ) forchunkinstream: print(chunk)Impact
This affects users who:
- Use API gateways or proxies that add SSE retry directives
- Work with streaming APIs that follow the SSE spec and include meta-fields
- Need reliable streaming in production environments
Proposed Solution
Add a check to skip events with empty/whitespace data before attempting JSON parsing:
# In Stream.__stream__() and AsyncStream.__stream__()forsseiniterator: ifsse.data.startswith("[DONE]"): break# Skip events with no data (e.g., standalone retry/id directives)# Per SSE spec, these are valid meta-only events that shouldn't be parsed as JSONifnotsse.dataorsse.data.strip() =="": continue# ... rest of processingPull Request
Fix submitted in #2721
The PR includes:
- Checks in both
Stream.__stream__()andAsyncStream.__stream__() - Test cases for retry directives and meta-only events
- Verification with production streaming workloads
Environment
- OpenAI Python SDK version: 2.6.1 (latest)
- Python version: 3.14
- Operating system: macOS