Repository navigation
Conversation
…de it Adds side chat and subagent rows to the fallback table that already covers snoozed and settled threads. Neither has a sidebar row, yet the thread opened after deleting the current one can be either, and both rows fail here.
…agent Deleting the thread you are looking at opens the newest other thread in its project. That pick reads every thread shell the environment streams, and the shells include side chats and running subagents, which live inside their parent and never get a sidebar row. When one of them was the newest, deleting the open thread dropped you into it on its own. pingdotgg#29891 fixed the same pick in the command palette's "open project" with isSidebarHiddenThread, and pingdotgg#29643 taught this fallback to skip snoozed and settled threads. The fallback now skips threads the sidebar does not list as well, with the same helper. Bug: deleting the open thread opens a side chat or subagent instead of a listed thread
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — After deleting the open thread, navigation now skips side chats and subagents hidden from the sidebar. The change only affects the fallback destination, not deletion or cleanup behavior. You can add or adjust custom eligibility rules. Learn more. |
Walkthrough
Merge Risk:
|
|
Note Written by Verified in a real dev environmentverified as-is at used repo-installed playwright and
runtime transcript from browser observations and read-only sqlite inspection: blacksmith passed inspected the captures and uploaded images; both uploaded recordings played and sought successfully in t3's browser player. Not verifiednative desktop, ios/android, macos/windows, remote/relay/tunnel connections, and providers other than codex were not exercised on this linux vm. bulk, sidebar, and command-palette deletion were not separately exercised. delegated-under-parent filtering remains outside the stated scope. |





Problem
Deleting the thread you are viewing opens the newest other thread in its project, but the pick includes side chats and running subagents, which have no sidebar row of their own. So the app can open a side chat or subagent on its own, or, when the pick is a side chat of the deleted thread, open an empty new draft even though other threads are listed.
Expected: the fallback skips side chats and subagents, as it already skips snoozed and settled threads.
Change
getFallbackThreadIdAfterDeletepicks from every thread shell the environment streams. It now also skips threads for whichisSidebarHiddenThreadis true, beside the snoozed and settled checks #29643 added. The thread type it accepts gainslineage, which the shells passed to it fromuseThreadActionsalready carry. When every other thread is skipped it returnsnullas before, and the app goes home.The empty-draft case: a
thread.deletecascades to the parent's side chats (Orchestrator.ts, "Side chats live inside their parent, so deleting the parent deletes them too"). Onmainthe fallback picks the side chat, the delete removes it,useThreadActionsthen finds no shell for it and navigates home, which opens a new draft.Every web delete path (sidebar menu, bulk delete, the thread header and command palette menu, side-chat deletes) goes through this one function, and desktop wraps web. Mobile has no "open the next thread after delete" step, and archive opens a new draft instead of picking a thread, so neither is affected.
Scope and approval
This is a small, focused fix for an obvious bug. #29891 fixed the same pick in the command palette ("opening a project from the command palette no longer lands in a subagent or side chat") with the same
isSidebarHiddenThreadhelper. #29643 taught this fallback to skip snoozed and settled threads but left side chats and subagents in. It changes no setting, contract or server behaviour. Like #29891, it does not widen the skip to the other threads the sidebar nests or filters, such as tasks a linked environment delegated here.Open #29666 edits the same function but repeats the already merged #29643, so the two overlap only in text.
Verification
apps/web/src/components/Sidebar.logic.test.tsgains two rows in the existinggetFallbackThreadIdAfterDeletetable, which already covers snoozed and settled threads. Each puts a newer side chat (lineageforkwithsideChat: true, asThreadForkServicecreates it) or subagent of another thread between a listed thread and the one being deleted.On
mainwith only the test commit (ba18c47),vp test run apps/web/src/components/Sidebar.logic.test.ts:With the fix: 92 passed.
vp run check:changed: format, lint, knip, typecheck (2 packages), tests (3 files) and the React compiler check pass.In a running dev build (web, Windows, the free Replay provider): in project
demo-repo, "Older thread" was started first, then "Thread A"./side what does clamp do?in Thread A started a side chat, which became the project's newest thread. Then Thread A was deleted from its thread menu.main): opens an empty new draftThe after run used a second thread, "Thread B", with its own side chat, since the before run had deleted Thread A. The captures are the preview panel's visible area (952 by 702), not the full window.
Bug: deleting the open thread opens a side chat or subagent instead of a listed thread
This was written with Claude Opus 5.5 in Claude Code, driven from T3 Code.