Skip to content

fix(web): deleting the open thread no longer opens a side chat or subagent - #30370

Open
spoukyii wants to merge 2 commits into
pingdotgg:mainfrom
spoukyii:users/spoukyii/delete-fallback-skips-side-chats
Open

spoukyii wants to merge 2 commits into
pingdotgg:mainfrom
spoukyii:users/spoukyii/delete-fallback-skips-side-chats

Conversation

@spoukyii

@spoukyii spoukyii commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

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

getFallbackThreadIdAfterDelete picks from every thread shell the environment streams. It now also skips threads for which isSidebarHiddenThread is true, beside the snoozed and settled checks #29643 added. The thread type it accepts gains lineage, which the shells passed to it from useThreadActions already carry. When every other thread is skipped it returns null as before, and the app goes home.

The empty-draft case: a thread.delete cascades to the parent's side chats (Orchestrator.ts, "Side chats live inside their parent, so deleting the parent deletes them too"). On main the fallback picks the side chat, the delete removes it, useThreadActions then 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 isSidebarHiddenThread helper. #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.ts gains two rows in the existing getFallbackThreadIdAfterDelete table, which already covers snoozed and settled threads. Each puts a newer side chat (lineage fork with sideChat: true, as ThreadForkService creates it) or subagent of another thread between a listed thread and the one being deleted.

On main with only the test commit (ba18c47), vp test run apps/web/src/components/Sidebar.logic.test.ts:

× skips a side chat thread the sidebar does not list
× skips a subagent thread the sidebar does not list
AssertionError: expected 'thread-parked' to be 'thread-visible' // Object.is equality
Tests  2 failed | 90 passed (92)

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.

Before (main): opens an empty new draft After (this branch): opens "Older thread"
Before: an empty new draft opens, though Older thread is listed After: Older thread opens

The 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.

…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
@github-actions github-actions Bot added the vouch:unvouched PR author is not yet trusted in the VOUCHED list. label Nov 3, 2026
@macroscopeapp

macroscopeapp Bot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 07c7b17

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.

@github-actions github-actions Bot added the size:XS 0-9 changed lines (additions + deletions). label Nov 3, 2026
@coderabbitai

coderabbitai Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Walkthrough

The delete fallback now excludes sidebar-hidden threads. Its candidate thread type requires lineage, and the tests cover side-chat forks and subagents.

Changes: Sidebar fallback

Layer / File(s) Summary
Fallback candidate filtering
apps/web/src/components/Sidebar.logic.ts, apps/web/src/components/Sidebar.logic.test.ts
getFallbackThreadIdAfterDelete now requires candidate threads to include lineage and excludes sidebar-hidden threads. Tests cover side-chat forks and subagents, along with snoozed and settled threads.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Low

Possibly related issues

  • Issue 29609 reports that delete fallback can select snoozed or settled threads that are not visible in the sidebar. This change excludes sidebar-hidden threads from fallback candidates.

Possibly related PRs

Suggested labels: size:S

Suggested reviewers: juliusmarminge

Merge Risk: Minimal · up to 07c7b

The requested side-chat and subagent behavior is addressed; delegated-thread fallback handling remains a minor follow-up.

Pre-merge checks: Passed 4
Check name Status Explanation
Title check Passed The title is concise, uses the repository's conventional format, and clearly identifies the main fix: preventing deletion from opening a side chat or subagent.
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.
Description check Passed The description includes the required Problem, Change, Scope and approval, and Verification sections. It explains the bug, implementation, scope, regression tests, check results, and manual UI evidenc…
Full details: Description check

Explanation

The description includes the required Problem, Change, Scope and approval, and Verification sections. It explains the bug, implementation, scope, regression tests, check results, and manual UI evidence. It also states the known verification limits.

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.
Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between d1ec71e and 07c7b17.

Files selected for processing: 2
  • apps/web/src/components/Sidebar.logic.test.ts
  • apps/web/src/components/Sidebar.logic.ts

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

@coderabbitai coderabbitai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Fix comments: Fix CodeRabbit comments on this PR

@maria-rcks

maria-rcks commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-6.1-sol on behalf of Maria

Verified in a real dev environment

verified as-is at 07c7b1798cad28edde6a7c7627fa614c2af13e5b on linux. no source changes needed.

used repo-installed playwright and /usr/bin/google-chrome against background vp run dev servers, one at a time. created a project with a real git repo, threads, and codex gpt-6.1-sol turns through the web app. no replay, mocks, fixtures, or seeded data.

  • on github/main at 7c22e24e3f, created "older thread ready", then "parent thread ready", then /side Reply with exactly: side chat ready. Do not use tools. deleting the parent through its header menu opened an empty draft despite the older thread remaining listed.
  • repeated matching project name, prompts, model, viewport, and deletion flow on the exact pr head. deletion opened the existing older thread and its real codex response. read-only sqlite inspection confirmed the parent and side chat were both deleted.
  • started a real native codex subagent under the older thread after creating another deletion target. deleting that target while the newer child ran opened the visible parent, skipped the child, and left it running. the child subsequently completed and its result reached the parent.
  • canceling deletion preserved the thread and route. with the remaining parent settled, deleting the last eligible thread opened a draft, skipping the settled parent, hidden child, and another project's thread. un-settle and reload preserved the older conversation.

runtime transcript from browser observations and read-only sqlite inspection:

main after parent deletion: /draft/fa3c80d6-60ec-4fa6-8dcc-a0312c73494d
pr expected older thread: 25f3cdf6-e832-46c8-8fbe-4b33bb125944
pr actual after parent deletion: 25f3cdf6-e832-46c8-8fbe-4b33bb125944
pr actual with running subagent: 25f3cdf6-e832-46c8-8fbe-4b33bb125944
subagent relationshipToParent=subagent; created 23:18:22Z
other target deleted 23:19:15Z; child still running
parent and side chat deleted_at=2026-11-03T23:16:25.563Z
no eligible candidate: /draft/8155fa91-4d76-4a77-91f2-c6c0802d1aa1

blacksmith passed vp test run apps/web/src/components/Sidebar.logic.test.ts (92 tests) and vp run check:changed refs/remotes/github/main: format, lint, both knip passes, affected typechecks, 94 sidebar unit/browser tests, and targeted react compiler check. installed missing base history and chromium on the worker before the successful run. git.cafe reports 30 successful checks, zero pending or failing.

main opens an empty draft while the older thread remains listed

pr opens the existing older thread and its codex response

pr opens the visible parent while its newer codex subagent continues running

main parent deletion recording

pr parent deletion recording

inspected the captures and uploaded images; both uploaded recordings played and sought successfully in t3's browser player.

Not verified

native 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.

This branch has not been deployed

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

Labels

size:XS 0-9 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants