Repository navigation
Conversation
…urn error The send path awaits the chat history query before sending. A concurrent invalidation (e.g. an SSE reconnect) cancels that joined read, so the send failed with CancelledError. Retry the wait on cancellation while the scope is current and the session still exists. Local dashboard errors were also merged into the preceding assistant response, which hid that turn's answer under "Worked for" and labelled it "This turn did not finish." Give them their own group and render them as a plain notice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…failures # Conflicts: # ui/dist/assets/PdfPreview-C7B2nDXs.js # ui/dist/assets/PdfPreview-CFkJL2GR.js # ui/dist/assets/PdfPreview-DvHMzgEY.js # ui/dist/assets/index-Ba-ecrFp.js # ui/dist/assets/index-CVY72FgI.js # ui/dist/assets/index-V63B47MD.js # ui/dist/index.html
[Medium impact] The changes affect chat sending and transcript display. The PR appears safe to merge, with a non-blocking gap in tests for the cancelled-history retry. Findings
Fix with agent prompt### Issue 1
ui/src/components/ChatPanel.tsx:5875-5882
The added test covers grouping, but no test checks that `CancelledError` retries the history read, waits for its replacement, and stops retrying after a workspace change or session deletion. The existing cancellation test still expects rejection and does not supply `CancelledError` or `deletedSessionIds` to its extracted-code test helper.
Add focused tests for these paths so a broken retry cannot silently bring back cancelled sends.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.SummaryThe PR retries cancelled history reads before sending and separates local failures from completed agent responses.
|
| const awaitHistory = (): Promise<unknown> => queryClient.fetchQuery({ | ||
| ...history, | ||
| ...(queryClient.getQueryState(history.queryKey)?.fetchStatus === "fetching" ? { staleTime: 0 } : {}), | ||
| }).catch((cause: unknown) => { | ||
| if (cause instanceof CancelledError && isCurrentScope(sessionsOptions.queryKey) && !deletedSessionIds.has(historySid)) return awaitHistory(); | ||
| throw cause; | ||
| }); | ||
| await awaitHistory(); |
There was a problem hiding this comment.
History retries lack test coverage
The added test covers grouping, but no test checks that CancelledError retries the history read, waits for its replacement, and stops retrying after a workspace change or session deletion. The existing cancellation test still expects rejection and does not supply CancelledError or deletedSessionIds to its extracted-code test helper.
Add focused tests for these paths so a broken retry cannot silently bring back cancelled sends.
Prompt To Fix With AI
This is a comment left during a code review.
Path: ui/src/components/ChatPanel.tsx
Line: 5875-5882
Comment:
**History retries lack test coverage**
The added test covers grouping, but no test checks that `CancelledError` retries the history read, waits for its replacement, and stops retrying after a workspace change or session deletion. The existing cancellation test still expects rejection and does not supply `CancelledError` or `deletedSessionIds` to its extracted-code test helper.
Add focused tests for these paths so a broken retry cannot silently bring back cancelled sends.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Summary
A side-chat user saw "This turn did not finish. / Message not sent: CancelledError" under a turn that had actually completed, and that turn's answer was hidden under "Worked for 1m 21s".
fetchQuery, so it rejected withCancelledError. The wait now retries onCancelledErrorwhile the workspace scope is current and the session is not deleted. The retry joins the replacement fetch, or reads the cache after a revert cancel.localErrormessages (send, resend and fork-switch failures) now carryLOCAL_ERROR_PART_ID. They start their own response group, so they no longer become the previous turn's "answer", and they render as a one-line notice instead ofTurnStatusRow's "This turn did not finish."Test plan
node --testUI suite (433/433), including a new grouping testtsc --noEmit, i18n check,vite build(ui/distregenerated)cargo fmt --check,cargo clippy -D warnings,cargo build --locked,cargo test --locked🤖 Generated with Claude Code