Treat missing thread snapshots as terminal#4235
Conversation
- Preserve authoritative thread-not-found snapshot failures - Mark missing threads deleted before opening socket subscriptions - Cover terminal missing-thread handling with sync tests - Document thread detail subscription reliability
- Delay draft detail loading until the server shell appears - Cover draft and normal thread subscription decisions - Document pre-creation draft synchronization behavior
- Verify decoded 404 and transient HTTP loader behavior - Cover draft detail subscription activation through the hook - Add structured metadata for terminal missing-thread cleanup
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Effect service review: one convention violation found. The new HTTP thread_not_found handling uses Effect.catchTag, but the conventions require Effect.catchTags for statically known tagged failures — including when handling a single tag.
Posted via Macroscope — Effect Service Conventions
ApprovabilityVerdict: Needs human review This PR changes how missing thread snapshots are handled from transient (retry) to terminal (mark deleted), affecting thread subscription lifecycle and state management. The behavioral change to error handling in critical synchronization code warrants human review. You can customize Macroscope's approvability policy. Learn more. |
- Match the convention for statically known tagged errors
Summary
Treat authoritative missing-thread snapshot responses as terminal client state instead of falling through to a repeatedly failing WebSocket subscription. Transient HTTP failures still retain the existing socket-snapshot fallback.
Delay detail synchronization for known local drafts until the server shell observes thread creation, preserving the legitimate pre-creation flow while preventing a missing-resource response from deleting the draft.
What Changed
thread_not_founderrors through the thread snapshot loader while mapping transient failures to socket fallback.BRANCH_DETAILS.md.Why
While investigating renderer memory growth from roughly 300 MB after launch to nearly 2 GB after extended use and idle time, stale thread details were observed being prewarmed after their server resources no longer existed. Each HTTP lookup returned authoritative
thread_not_found, but the client treated that as a transient miss, opened a WebSocket subscription that also failed, and retried the cycle every 250 ms. Multiple stale subscriptions made this a concrete source of sustained allocation, retained state, and background CPU pressure, though it should not be assumed to explain every byte of renderer memory growth by itself.The terminal handling stops that loop and evicts the stale persisted detail. Because a brand-new local draft also legitimately has no server thread before its first send, draft detail synchronization now waits for the shell's creation signal so the fix does not turn that expected pre-creation 404 into a deleted draft.
Validation
Proof
No additional proof artifacts are required; the focused automated coverage and integrated browser flow exercise the affected lifecycle directly.
Note
Medium Risk
Changes core thread sync and deletion semantics for HTTP 404s and draft routes; wrong classification could delete live threads or leave stale subscriptions, though behavior is covered by new tests.
Overview
Stops stale thread-detail sync from retrying forever when the server says the thread is gone, and avoids treating a pre-creation draft as deleted.
HTTP
thread_not_foundis authoritative.ThreadSnapshotLoaderno longer maps a decoded 404 intoOption.nonefor socket fallback; it keepsEnvironmentResourceNotFoundErrorin the error channel. InmakeEnvironmentThreadState, that path clears persisted detail, sets status deleted, logs diagnostics, and interrupts before opening or retrying the WebSocket subscription. Other HTTP snapshot failures still becomeOption.noneand use the existing socket path.Local drafts wait for a server shell.
useThreadgates detail subscription throughshouldSubscribeToThreadDetail: known composer drafts do not subscribe to server detail untilthreadShellexists, so the expected pre-creation 404 cannot mark the draft deleted.Adds focused tests for the HTTP loader, thread sync harness, and web hook lifecycle, plus
BRANCH_DETAILS.mddocumenting the contract.Reviewed by Cursor Bugbot for commit 8b86c84. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Treat missing thread HTTP snapshots as terminal by marking threads deleted
ThreadSnapshotLoader.loadreceives an authoritative HTTP 404 (thread_not_found), the effect now fails withEnvironmentResourceNotFoundErrorinstead of returningOption.noneand falling back to a WebSocket subscription.EnvironmentThreadState.makecatches this error, marks the thread as deleted, and interrupts the subscription workflow, skipping the WebSocket entirely.useThreadnow gates detail subscription via a newshouldSubscribeToThreadDetailfunction, delaying subscription for local draft threads until a server shell is observed.Macroscope summarized 8b86c84.