fix: prevent request_id desync from background events and duplicate Stopped - #40
Merged
Merged
Conversation
…topped Three fixes for the systematic n-1 response shift where each message gets the response for the previous message: 1. EntryUpdated uses turn-scoped request_id with prev_turn fallback: Claude Code delivers background events (tool completions, text flushes) asynchronously via session_notification after a turn ends. EntryUpdated now checks whether the entry belongs to the current turn (>= turn_start) or a previous one, and tags it with the correct turn's request_id. Previously it read the global THREAD_REQUEST_MAP which could already point to the next turn. 2. NewEntry updates turn_request_id only at turn boundaries: turn_request_id is now only updated from the global map when current == last_completed (i.e. a new turn is starting). The old value is rotated into prev_turn_request_id for use by late EntryUpdated events from the previous turn. 3. Guard normal-completion Stopped against duplicate emission: When cancel() races with natural turn completion, both paths could emit Stopped. The duplicate triggers the stale-detection fallback which reads the global map (now pointing to the next turn's request_id), sending a premature message_completed that shifts all subsequent responses by one. Added stopped_emitted_for_task check to the normal completion path, matching the existing guard on the cancelled path. Documented as Critical Fix #9 in portingguide.md. E2E tests pass for both zed-agent and claude (all 10 phases). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
lukemarsden
added a commit
to helixml/helix
that referenced
this pull request
Apr 14, 2026
Bump ZED_COMMIT to pick up helixml/zed#40 which fixes the systematic n-1 response shift caused by: - Background events from Claude Code tagged with wrong request_id - Duplicate Stopped events from cancel/completion race Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2 tasks
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
Test plan
cargo check -p external_websocket_syncandcargo check -p acp_threadpass🤖 Generated with Claude Code