Skip to content

fix(web): prevent infinite re-render loop in Sidebar (React error #185)#20

Merged
Jay1 merged 4 commits into
mainfrom
jcode/fix-react-error-185-crash
May 28, 2026
Merged

fix(web): prevent infinite re-render loop in Sidebar (React error #185)#20
Jay1 merged 4 commits into
mainfrom
jcode/fix-react-error-185-crash

Conversation

@Jay1
Copy link
Copy Markdown
Owner

@Jay1 Jay1 commented May 28, 2026

Problem

React minified error #185 ("Maximum update depth exceeded") crashes the web app during active LLM chat, showing the "Something went wrong" error boundary and requiring constant reloads.

Root Cause

A useEffect in Sidebar.tsx depends on standardProjects, which gets a new array reference on every store update during active chat. The dependency chain:

  1. SSE events update sidebarThreadSummaryById
  2. createSidebarThreadSummariesSelector produces new sidebarThreads
  3. sortProjectsForSidebar always returns a new array ([...projects].toSorted(...))
  4. standardProjects = sortedProjects.filter(...) — also always new
  5. useEffect fires and calls setExpandedThreadListsByProject unconditionally

Even though pruneExpandedProjectThreadListsForCollapsedProjects returns the same Set reference when no pruning is needed, the setState call still schedules a render. Under rapid SSE events during streaming, this exceeds React 19's nested update limit.

Note: React 19 issue #36423NESTED_PASSIVE_UPDATE_LIMIT is __DEV__-only, so in production the loop runs silently rather than throwing early.

Fix

Add a useRef<ReadonlyMap<string, boolean>> that tracks the previous cwd -> expanded mapping for projects. The useEffect now compares the current mapping against the previous one and skips setExpandedThreadListsByProject when no project's expanded status actually changed — only when the reference changed due to unrelated store updates.

Testing

  • 121 test files / 1374 tests pass
  • TypeScript typecheck clean
  • Production build verified: guard confirmed in minified output (n&&snip Je(e=>Vgt({...})))

The useEffect that calls setExpandedThreadListsByProject fires on every
standardProjects reference change. During active LLM chat, SSE events
cause sidebarThreadSummaryById to update frequently, which cascades
through sortProjectsForSidebar (always creates a new array) to
standardProjects (filter, also always new), triggering the effect on
every streaming update.

The prune function itself returns the same Set reference when no pruning
is needed, but the setState call still schedules a render. Under rapid
SSE events this exceeds React 19's nested update limit, producing
minified error #185 (Maximum update depth exceeded).

Fix: track the previous project cwd->expanded mapping in a ref. Only
call setExpandedThreadListsByProject when a project's expanded status
has actually changed, not just when the standardProjects array got a
new reference.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 28, 2026

Warning

Review limit reached

@Jay1, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 4 minutes and 3 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 38bae426-3b11-4db2-803e-d8c947158f38

📥 Commits

Reviewing files that changed from the base of the PR and between fb865f3 and 3053367.

📒 Files selected for processing (2)
  • README.md
  • apps/web/src/components/Sidebar.tsx
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jcode/fix-react-error-185-crash

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.

❤️ Share

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

@github-actions github-actions Bot added size:S vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. labels May 28, 2026
@Jay1 Jay1 self-assigned this May 28, 2026
@Jay1 Jay1 merged commit 7286c8d into main May 28, 2026
8 checks passed
@Jay1 Jay1 deleted the jcode/fix-react-error-185-crash branch May 28, 2026 18:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S 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.

1 participant