Skip to content

fix(web): clear stale messages when switching threads - #17489

Closed
extoci wants to merge 1 commit into
pingdotgg:mainfrom
extoci:t3/clear-stale-thread-content
Closed

extoci wants to merge 1 commit into
pingdotgg:mainfrom
extoci:t3/clear-stale-thread-content

Conversation

@extoci

@extoci extoci commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Problem

Switching to an uncached thread updates the sidebar, title, and composer immediately, but the chat continues showing the previous thread's transcript until the destination loads. This affects the shared Web/Desktop chat view and matches the stale-transcript portion of #17115.

Change

Remove the fallback that paints the last-viewed thread's messages. A loading thread now shows only its own cached messages, or an empty timeline until its detail arrives. Cached destinations still appear immediately. Remove the cross-thread rendering guards and workspace snapshot fields that existed solely to support that fallback.

Scope and approval

This is a focused fix for an obvious thread-identity mismatch: messages from thread A must not appear under thread B's title. The change stays within the shared chat view and its tests, with no transport, provider, or native mobile changes. Submitted under the small, focused bug-fix exception in CONTRIBUTING.md.

Verification

  • Regression tests failed before the fix: selecting loading thread B returned thread A's entries and display identity. They pass with the fix, including rapid switches, cached destinations, resolved empty threads, and matching thread IDs in different environments.
  • After rebasing onto main at ec80933ac8: vp test run apps/web/src/components/ChatView.logic.test.ts apps/web/src/components/chat/MessagesTimeline.logic.test.ts apps/web/src/threadRoutes.test.ts — 293 passed.
  • vp run --filter @t3tools/web typecheck — passed.
  • Targeted lint completed with warnings; formatting and diff checks passed.
  • Real Browser panel verification, recorded before the rebase: two mock conversations in an isolated dev instance, with the destination snapshot delayed three seconds in both versions. Before: B's header appeared with A's landing-page messages. After: A's messages cleared immediately and B's checkout messages appeared when loading completed. Returning to cached A showed A immediately. The mock state, temporary fixtures, Browser tab, and dev server were cleaned up.
  • Electron was not run separately; it uses the same chat view.

Before/after screenshots during the same loading state:

Before and after loading thread B

Before/after recording (before on the left, after on the right):

Before and after thread switching

Full-size recordings: before · after.

Implemented and verified with GPT-6.1-Sol through the Codex harness in T3 Code.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Oct 9, 2026
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Oct 9, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 4d0d490

Macroscope's review found this PR approvable — This is a focused, deletion-heavy fix that stops previously viewed messages from appearing while another thread loads, while preserving per-thread caching and immediate rendering for cached destinations. The behavior is isolated to the shared chat view and covered by targeted transition tests.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 50c700f5-afbe-454b-9734-fb6afc0488a5

📥 Commits

Reviewing files that changed from the base of the PR and between 665266c and 4d0d490.


📒 Files selected for processing (1)
  • apps/web/src/components/ChatView.tsx

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.



📝 Walkthrough

Walkthrough

Thread switching now uses remembered entries for the active thread instead of showing another thread’s last-ready timeline. ChatView passes active-thread data and behavior to MessagesTimeline.

Changes

Thread timeline switching

Layer / File(s) Summary
Remembered timeline resolution
apps/web/src/components/ChatView.logic.ts, apps/web/src/components/ChatView.logic.test.ts
The resolver remembers entries by thread key and uses them only for the active thread while loading. Tests cover uncached destinations, rapid switches, and matching thread IDs in different environments.
Active-thread timeline rendering
apps/web/src/components/ChatView.tsx
ChatView removes held-timeline handling and passes active-thread data and behavior to MessagesTimeline. Timeline actions, search availability, provider status, and thread environment use the active thread.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant ChatView
  participant TimelineResolver
  participant MessagesTimeline
  ChatView->>TimelineResolver: Resolve entries for the selected thread
  TimelineResolver-->>ChatView: Return next or remembered entries
  ChatView->>MessagesTimeline: Render entries with active-thread data and actions
Loading

Suggested reviewers: flamboh


Merge Risk | ⚪ Minimal · up to 4d0d4

Merge Risk: ⚪ Minimal · up to 4d0d4

Switching threads now shows only the destination thread's own messages, or an empty timeline while it loads, and timeline actions follow the active thread. No concrete merge-blocking risk was found.

Security Architecture Review

Security architecture risk: ⚪ Minimal · up to 4d0d4

The fix aligns displayed messages and actions with the selected thread. Comparing the previous and updated behavior found no material increase in cross-thread access, command authority, or security exposure.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — For the reviewed timeline flow, effective command targeting remains the selected environment and thread. Removing the fallback prevents a different cached thread’s messages from supplying actions under the destination’s context; it does not grant authority over all cached threads.

Security Findings and Attack Paths

  • inferred — The removed paint-only guards do not establish a newly reachable cross-thread attack path: active-thread cached entries were already actionable at the base, while the foreign-thread entries that required suppression are no longer selected. No introduced or materially worsened security condition was identified in this comparison.

Trust Boundaries and Controls

  • observed — Checkpoint controls pass checkpoint and scope IDs to the existing rollback handler, which dispatches with its captured environment and active thread after confirmation and busy/environment checks. Conversation revert additionally checks orchestration-operate scope and requires a user message from the active projection. These controls are unchanged by the PR.

Resilience and Maintainability Implications

  • observed — Rewind status remains route-key scoped. The checkpoint handler reports returned non-interruption failures and removes the marker after returned outcomes; conversation revert uses finally cleanup and avoids updating another route’s composer UI after completion. These unchanged source paths support ownership containment but do not prove backend atomicity or concurrency safety.

Pre-merge checks | Passed 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check Passed The title clearly and concisely describes the primary fix: removing stale messages when switching threads.
Description check Passed The description covers the problem, change, scope and approval rationale, and detailed verification results. It includes UI screenshots and recordings, identifies unverified Electron coverage, and sta…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@extoci
extoci force-pushed the t3/clear-stale-thread-content branch from ec8b847 to 665266c Compare October 9, 2026 23:44
@extoci
extoci force-pushed the t3/clear-stale-thread-content branch from 665266c to 4d0d490 Compare October 12, 2026 12:05
@macroscopeapp
macroscopeapp Bot dismissed their stale review October 12, 2026 12:05

Dismissing prior approval to re-evaluate 4d0d490

@juliusmarminge

Copy link
Copy Markdown
Member

Note

Grok responding on behalf of Julius.

Thanks for this! #21560 just landed on main and fixes the same stale-transcript problem from #17115 (a loading thread now shows only its own cached messages or its loading state), so I'm closing this one as superseded. If you still see the old transcript flash on a build with #21560, please open a new issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants