Repository navigation
fix(sse): keep a clean empty Claude end_turn - #15505
Merged
diegosouzapw merged 2 commits intoOct 6, 2026
Merged
diegosouzapw merged 2 commits into
diegosouzapw merged 2 commits into
Conversation
A streamed Claude turn that reaches message_stop with end_turn or stop_sequence and no content block is a real empty answer. The flush check aborted every lifecycle that had no content block, including that one. content_filter, a missing stop, a missing message_stop, and a zero-byte stream still abort. Related to diegosouzapw#15488. Signed-off-by: Minxi Hou <houminxi@gmail.com>
The stream change needs its own changelog fragment so release aggregation picks it up. Signed-off-by: Minxi Hou <houminxi@gmail.com>
diegosouzapw
merged commit Oct 6, 2026
588ccb7
into
diegosouzapw:release/v3.8.52
44 of 51 checks passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
message_stop,stop_reasonend_turnorstop_sequence, and no content block was turned into 502Claude returned an empty response (no content block). Claude Code's prompt-suggestion request asks for a short guess or nothing, so an empty answer is valid.message_delta.delta.stop_reasonis now kept on the stream lifecycle. The flush check leaves that finished empty turn alone.content_filter, a missing stop reason, a lifecycle that never reachesmessage_stop, and a zero-byte stream still abort.Validation
node --import tsx/esm --test tests/unit/stream-claude-empty-end-turn.test.ts tests/unit/stream-empty-response-retry-96ef4a.test.ts— 12 pass, 0 failstopReasonwrite makes only the wiring test fail. The decision tests stay green.review-default. All four had 0 CONFIRMED. Round 2 was PASS with clean 2. Rounds 1, 3, and 4 were PENDING because of UNCERTAIN notes: a guessed top-levelstop_reason(fixtures in this repo usedelta.stop_reason), a null payload (the type check already returns), and a claim thatmax_tokens/tool_useshould also pass. Those two stay failures on purpose. One note was an excerpt line count.Tests Added Or Updated
tests/unit/stream-claude-empty-end-turn.test.tsend_turnandstop_sequencewith a complete lifecycle do not abortcontent_filter, a missing stop reason, a missingmessage_stop, and a zero-byte stream still abortmessage_deltastoresdelta.stop_reason, and that stored value is what the decision readsCoverage Notes
Reviewer Notes
end_turnflagged there on purpose.Provider returned empty contenton a Codex stream) is a different check. Its report did not include the upstream finish reason, sostopwas not added to that allowlist.