Repository navigation
Conversation
…en its run starts Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — Attachment removal now counts as an unsaved queued-message edit when its run starts, and cleared edits are reported as discarded. The change is limited to local draft recovery and notifications, while preserving existing thread drafts. You can add or adjust custom eligibility rules. Learn more. |
|
| Layer / File(s) | Summary |
|---|---|
Track attachment removal during recovery apps/web/src/components/chat/useQueuedRunEdit.ts, apps/web/src/components/chat/queuedMessageEdit.ts, apps/web/src/components/chat/queuedMessageEdit.test.ts |
The queued-run edit state records attachment removal and passes it to recovery. Recovery considers the removal when deciding whether an edit changed and whether the thread draft is empty. A test covers nonempty original text and an attachment-only edit. |
Estimated code review effort: 2 (Simple) | ~10 minutes
Change: Bug fix
Possibly related issues
pingdotgg/t3code#15611— Both concern queued-edit behavior when a run starts. This change handles recovery when a run leaves the queue; it does not add the dispatch guard described in the issue.
Suggested reviewers: juliusmarminge
Merge Risk: 
Low · up to fa865
-
Recovered drafts can omit retained attachments. This is a bounded recovery risk; users should check attachments before resending.
Pre-merge checks: 
4
-
Full details: Description check
-
Explanation
The description is complete and follows the required template. It explains the problem, change, scope and approval rationale, focused verification results, UI evidence, known limitations, and the agent and harness used.
-
Finishing Touches
-
Generate unit tests (beta)
-
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
CodeRabbit Verify
- Run CodeRabbit Verify to test the changes in this pull request.
|
Note Written by Merged main without conflicts and preserved the three-file fix. All 31 checks are green on |
|
Note Written by Verified in a real dev environmentVerified unchanged head
Read back the running server's bounded thread projection using its protocol header:
Main: the edit closes silently and the composer is empty. PR: the text is recovered and the notification explains what happened. Recording: remove the attachment, dispatch from the second client, and observe recovery in the first client. Not verifiedNative Electron, iOS and Android clients, macOS/Windows, remote relay/tunnel connections, and providers other than Codex were not exercised on this Linux VM. The recorded exit uses the second client's Send now action; automatic queue advancement with the unsaved edit still open was not separately verified. This PR changes web recovery logic. |




Problem
In the web composer, you can edit a queued message and remove one of its attachments. That removal didn't count as a change. If the run then left the queue before you saved (another client started or cancelled it, or the turn ended), the edit closed with no notice. The message ran with the attachment you had removed, and nothing told you your edit was gone.
Change
The edit now records that an existing attachment was removed, and
recoverQueuedMessageEdittreats that as a change. It also keeps an edit only when there is something to put back in the composer. Otherwise, an attachment-only message with one attachment removed would say "kept in the composer" while leaving the composer empty. In that case the edit is reported as discarded.This copies the mobile sibling,
exitQueuedRunEditinapps/mobile/src/state/queued-run-edit.ts. Since #25468, mobile tracksremovedExistingAttachment("Removing a server attachment changes the message even when the draft looks untouched") and keeps an edit only when it has restorable content.Scope and approval
Very small, focused fix for an obvious bug, so no prior issue. Mobile already treats removing a queued attachment as an edit. Web dropped that edit with no notice. Web only, 3 files.
Overlap search: the local PR index and GitHub (
queued edit removed attachment) found nothing. #29570 releases staged uploads when a queued edit is discarded. It touches the same function's discard branch but not how a change is detected. #28086 and #18631 hold a queued run while it is being edited. Neither changes how web detects a change, and an exit can still happen without a hold (older servers, a cancel from another client).Verification
main: I added a case toqueuedMessageEdit.test.ts("reports a removed queued attachment as an edit when the run leaves"). It fails withAssertionError: expected 'clean' to be 'kept'.vp test run src/components/chat/queuedMessageEdit.test.tspasses, 6 tests. I reran it after rebasing on the latestmain.vp run check:changedpasses: format, lint, knip, typecheck (2 packages), tests (2 files), and the React compiler check.Reviewed with sol-loop: 1 round with GPT-6.1 Sol on high. Sol verdict: approved.
Created with Claude Opus 5.5 in Claude Code (T3 Code).
🤖 Generated with Claude Code
Takeover verification
Merged current main without conflicts in
dc055f44dbae3d529764c4c27edc9dcf2a21b3ab. No implementation changes beyond the original three-file fix. All 31 CI checks are green.vp run check:changed github/mainpassed through blacksmith-check, including lint, typecheck and 13 focused tests. Two independent GPT-6.1 Sol reviewers approved this head.The separate timeline-heading test failed identically on this head and main (
expected 577 to be close to 473); left unchanged. The PDF preview test passed on rerun. Native desktop and mobile were not exercised; this change is web-only.Takeover verification by gpt-6.1-sol in the Codex harness through T3 Code.