18:15:03.019Z
[v0] Sending chunk 2 size: 83
18:15:03.189Z
[v0] Sending chunk 4 size: 83
18:15:03.201Z
[v0] EventSource error - readyState: 2 event: {"isTrusted":true}
18:15:03.201Z[SERVER]
[v0] GET /api/stream - Starting upstream fetch
18:15:03.634Z[SERVER]
[v0] Upstream response received - status: 200
18:15:03.634Z[SERVER]
[v0] Upstream headers: {"contentType":"text/event-stream","transferEncoding":"chunked","contentLength":null}
18:15:03.634Z[SERVER]
[v0] Creating transform stream
18:15:03.634Z[SERVER]
[v0] Returning streaming response
it seems like the backend keeps sending but the frontend errors right away
I see the issue now! The logs show chunks ARE being sent (both server and client show multiple chunks of 83 bytes), but EventSource closes immediately. The problem is likely that EventSource expects the first message to be a valid SSE format, but it's getting something it doesn't recognize. Let me check the actual data by removing the charset parameter and ensuring proper SSE formatting:
I see the issue—the charset=utf-8 parameter in Content-Type might be causing EventSource to fail. Some browsers are strict about the Content-Type format for EventSource. Let me simplify it to just text/event-stream:
Now let me also add additional headers that some browsers require for EventSource:
Now let me add a log to actually read one chunk and see what format the data is coming back in:
I've removed the charset parameter which was likely causing EventSource to reject the response. I've also added logging to show what the first chunk of data actually looks like so we can see if it's valid SSE format. Try starting the stream again and share the new logs—especially the "First chunk sample" log which will reveal the actual data format.
Now let me rewrite the stream-viewer to use fetch() with ReadableStream instead of EventSource:
I've switched from EventSource to using the Fetch API with ReadableStream. The key differences:
fetch() with response.body.getReader() instead of EventSource to get direct stream accessdata:, event:, and : (comments) prefixesAbortController to cleanly stop the stream instead of closing an EventSourceThis gives us the raw streaming capability without EventSource's parsing restrictions. The frontend now properly handles the streamed data by buffering incomplete lines and processing complete ones.