Skip to content

[Bug]: Settled shelf crashes the app with React #185 when the sidebar filter has more than one project #27168

Closed

Description

@jagrat7

What happened

The desktop app crashed with "Something went wrong. Minified React error # 185" (Maximum update depth exceeded) after I'd been looking at the Pull Requests page for a while and then switched views. After that the app was unusable: Try again and Reload app both went straight back to the same error, on every route.

Diagnosis

The first crash's stack goes through the olderSettledShelf chunk into React's scheduleUpdateOnFiber → throwIfInfiniteUpdateLoop. The setState that loops is useOlderSettledShelfGrowth (apps/web/src/state/olderSettledShelf.ts:94-96). That effect calls grow(wanted) whenever wanted !== pages, and wanted is a new Map whenever wantedOlderSettledPages decides one more page is needed.

Why reloading doesn't help: whether the Settled shelf is expanded is persisted in localStorage (t3code:sidebar:settled-expanded, apps/web/src/components/Sidebar.tsx:428). The sidebar is mounted on every route, so once the loop has happened with the shelf expanded, every launch and route hits it again. Setting that key to false brought the app back immediately.

The shelf was added in #24723 (Oct 25). No commit to olderSettledShelf.ts / olderSettledThreads.ts since this build changes the growth logic.

What I ruled out / am unsure of:

  • Server pagination looks correct: listOlderSettledThreads orders by (settled_at DESC, thread_id ASC) with a matching tie-break cursor. The DB has 403 settled threads, all with distinct, uniformly formatted (24-char ISO) settledAt values, so a cursor that never advances on ties is unlikely.
  • For a synchronous loop, the effect has to see wanted !== pages on 50+ consecutive commits. One way that can happen is scopeKey (from olderSettledScopes([...serverConfigs.keys()], scopedProjectKeys)) differing between consecutive renders. requested.scopeKey !== scopeKey then makes pages fall back to NO_PAGES every render, so wanted is always a fresh {env: 1} map and grow fires again. This is a hypothesis, not confirmed; it fits "switched views" as the trigger.
  • A second crash a minute and a half later, on a /draft/... route, had a different stack (combobox → P4.setState). It may be a separate loop, or a consequence of the same state; I couldn't tell.

Steps to reproduce

Not deterministic yet. What happened:

  1. With the sidebar's Settled shelf expanded (the user has 403 settled threads, so older ones load in pages), open Pull Requests and stay there a while.
  2. Switch to another view/project.
  3. The app shows React error Add drag-and-drop project reordering to the sidebar #185. Every reload crashes again until t3code:sidebar:settled-expanded is set to false.

Expanding the shelf again and repeating Pull Requests → switch view afterwards did not reproduce it, so the trigger seems to need more than "expanded + switch".

Version

Desktop app 0.1.4-nightly.20261028.3841 (local server reports the same serverVersion). The triage CLI was 0.1.5.

Environment

Linux x64 (Omarchy, kernel 7.2.8), Node v26.12.1, desktop app against the local server on 127.0.0.1.

Evidence

# Crash 1
T3 Code (Nightly) 0.1.4-nightly.20261028.3841
Path: /pull-requests
Time: 2026-10-29T21:22:42.238Z

Error: Minified React error #185
    at Pi (t3code://app/assets/dist-DcfUooDF.js:34:28269)
    at ji (t3code://app/assets/dist-DcfUooDF.js:34:27794)
    at fc (t3code://app/assets/dist-DcfUooDF.js:34:60319)
    at dc (t3code://app/assets/dist-DcfUooDF.js:34:59941)
    at j (t3code://app/assets/olderSettledShelf-DXYTBlPt.js:1:1066)
    at c (t3code://app/assets/olderSettledShelf-DXYTBlPt.js:1:2477)
    at wl (t3code://app/assets/dist-DcfUooDF.js:34:94992)
    at Uu (t3code://app/assets/dist-DcfUooDF.js:34:118178)
    at Hu (t3code://app/assets/dist-DcfUooDF.js:34:117951)
    at Uu (t3code://app/assets/dist-DcfUooDF.js:34:119394)

# Crash 2
Path: /draft/<draft-id>
Time: 2026-10-29T21:24:11.959Z

Error: Minified React error #185
    at Pi (t3code://app/assets/dist-DcfUooDF.js:34:28269)
    at Mi (t3code://app/assets/dist-DcfUooDF.js:34:27842)
    at Cs (t3code://app/assets/dist-DcfUooDF.js:34:53911)
    at t3code://app/assets/dist-DcfUooDF.js:34:53792
    at P4.setState (t3code://app/assets/utils-Ct-AKQrk.js:23:79691)
    at P4.update (t3code://app/assets/utils-Ct-AKQrk.js:23:79762)
    at t3code://app/assets/combobox-Cm1W01vR.js:1:14047
    at wl (t3code://app/assets/dist-DcfUooDF.js:34:94992)

Related issues

None found for the Settled shelf / olderSettledShelf. Earlier #185 loops (#9390, #11308, #12891, #14959, #15120) are closed and involve other components. #26467 is about older settled thread links, not a crash.

Fix applied or workaround

In DevTools (Ctrl+Shift+I) on the crash screen: localStorage.setItem("t3code:sidebar:settled-expanded", "false"), then Reload app. The app loaded normally afterwards. Nothing else was changed on the machine.

Filed by

Claude Code (Claude Opus 5.5, claude-opus-5-5) via t3 triage

Activity

  1. jagrat7 commented on Oct 29, 2026

    @jagrat7
    ContributorAuthor

    Update: reproducible with a multi-project sidebar filter

    The trigger is the project filter. On the same machine and build (0.1.4-nightly.20261028.3841):

    • All projects, or a single project in the filter: expanding Settled is stable.
    • Two or more projects in the filter: expanding Settled makes the list stutter and re-open over and over, then the app crashes with React Add drag-and-drop project reordering to the sidebar #185. Because t3code:sidebar:settled-expanded stays true, it keeps crashing until that key is reset.

    In the user's screenshot, the shelf header says 63 but lists only 7 rows, below SETTLED_TAIL_INITIAL_COUNT (10). So useOlderSettledShelfGrowth keeps asking for more pages.

    Likely mechanism (from source; the ordering flip is inferred, not observed)

    1. With a multi-project filter, olderSettledScopes (apps/web/src/components/Sidebar.tsx:694) builds projectIds in the iteration order of chosenScopeProjectKeys (Sidebar.tsx:1057), which follows projectGroups order. useSidebarProjectGroups sorts that by activity over useQuietThreadShells(); the sort order here is the default updated_at.
    2. useOlderSettledShelf keys its requested pages on scopeKey = JSON.stringify(input.scopes) (apps/web/src/state/olderSettledShelf.ts:30), which is order-sensitive. The atom side, pagesKey in packages/client-runtime/src/state/olderSettledThreads.ts:311, sorts projectIds.
    3. Mounting a loaded page (threadFamilies.mountRows) adds older rows to the thread shells, which can reorder the project groups. The projectIds order flips, scopeKey changes, requested.scopeKey !== scopeKey, and pages falls back to NO_PAGES. The mounted rows are released, the order flips back, and useOlderSettledShelfGrowth calls grow() again. That oscillation is the visible stutter, and it ends in "Maximum update depth exceeded".

    With one project there's no order to flip, which fits single-project and All projects being stable.

    Possible fix direction: make the shelf's scope identity order-independent. For example, sort projectIds (and scopes by environmentId) in olderSettledScopes or before computing scopeKey, the same way pagesKey already sorts.

    Repro

    1. Have enough settled threads that some are older than the shell cut (this user has ~400).
    2. In the sidebar project filter, select two or more projects.
    3. Expand Settled: the list stutters and the app crashes with React Add drag-and-drop project reordering to the sidebar #185. Every reload crashes until localStorage["t3code:sidebar:settled-expanded"] is set to false.

    The second stack from the original report (combobox → P4.setState on /draft/...) is still unexplained. It may be the project-filter combobox, given the trigger above.

    Claude Code (Claude Opus 5.5, claude-opus-5-5) via t3 triage

  2. changed the title [-][Bug]: Settled shelf in the sidebar crashes the desktop app with React #185, and every reload crashes again[/-] [+][Bug]: Settled shelf crashes the app with React #185 when the sidebar filter has more than one project[/+] on Oct 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions