Skip to content

Malformed SSE chunk drops already-streamed text from history #62

Closed

Description

@FernandoCelmer

Bug

`GenericProvider._stream` (`pycodeloop/providers/generic.py:397`) does `chunk = json.loads(payload)` with no `try/except`. If an OpenAI-compatible endpoint sends a truncated/corrupt `data: ` line mid-stream (network blip, proxy cutting the body, etc.), that `json.loads` raises.

Trace

By that point, `on_delta(...)` (lines 413-424) has already fired for every prior chunk — those `chat/textDelta` notifications already reached the client and rendered in the UI. But the exception propagates up through `Agent._complete`; since it's not `TimeoutError`/`ConnectionError` it isn't retried, the turn fails, and `session.add_assistant(...)` is never called. The text the user already saw on screen never enters the persisted session — reloading the session shows the conversation without that reply.

Fix

Wrap the malformed-chunk case so streaming degrades gracefully instead of losing already-shown text — e.g. catch the JSON decode error, stop consuming the stream, and still persist whatever text/tool-calls were accumulated so far (similar to how a clean `stop_reason` is handled), rather than letting the exception discard everything.

Activity

  1. added 2 commits that reference this issue on Aug 16, 2026
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

    bugSomething isn't workingin progressIssue being actively worked on

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions