-
Notifications
You must be signed in to change notification settings - Fork 12
Fix blank code blocks in assistant #5772
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
backspace
wants to merge
8
commits into
main
Choose a base branch
from
assistant-blank-blocks-cs-12491
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
f6b5566
Stop restarting a code diff that is already loading
backspace 283ba0e
Show the pending header only while a diff is loading
backspace fe6879a
Cover the parts of the diff resource that had nothing holding them
backspace f3d3f89
Check ownership after every await in the diff load
backspace 38155d6
Ask which pane shows the replacement rather than guessing an index
backspace 46d5fc2
Observe the clobber through an error, not the diff editor
backspace ca418d6
Merge remote-tracking branch 'origin/main' into assistant-blank-block…
backspace 3391d1d
Merge remote-tracking branch 'origin/main' into assistant-blank-block…
backspace File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
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
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
Oops, something went wrong.
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the inputs change after
getSourceresolves but whileApplySearchReplaceBlockTool.execute()is awaiting its module load, cancelling this restartable task stops only the outer task at thisawait;loadDiff()is a separate ordinary async operation, and the abort signal no longer stops it after the fetch. The superseded operation can therefore later overwriteoriginalCode,modifiedCode, orerrorMessagebelonging to the newer patch (and can also mutate after destruction), displaying or copying a stale diff. Keep the state-mutating awaits directly in the task or verify the controller/signal after every await before assigning resource state.Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Claude Code 🤖] Real bug, and precisely diagnosed. Fixed in f3d3f89.
You're right about the boundary:
loadDiffis an ordinary async function, so cancelling the task only stops things at theawaitinside the task body. Past that, the abort signal reaches the fetch and nothing else —ApplySearchReplaceBlockTool.execute()awaits a module load with no knowledge of it.Worth naming the exact hole, because it wasn't where I'd assumed. The
catchaftergetSourcealready hadif (signal.aborted) return, so I'd covered the fetch rejected mid-flight case. What was uncovered was the success path — a fetch that completed before the supersession, followed by anexecute()that spans it. That run then resumed and assignedoriginalCode,modifiedCode, anderrorMessagebelonging to the newer patch.Took the second of your two options — verify after every await — rather than moving the work into the task body, because it holds regardless of how ember-concurrency cancels an async task, and I didn't want the correctness of this to rest on my reading of those internals.
…and the same guard on both the resolve and reject paths of
execute(). One related change your comment implies: the patch is now applied againstoriginalCode— the value this load fetched — instead ofthis.originalCode, which by then may belong to a different patch entirely.The destruction case you mention falls out of the same guard, since the destructor aborts the controller.
Added a regression test that forces the ordering deterministically: two loads started with a deferred
getSource, the newer one released and allowed to render its diff, then the abandoned one released afterwards. It asserts the diff still shows the newer replacement. Against the previous code the late load overwrites it.Not verified locally — Colima is down here, so CI is exercising it.