Repository navigation
fix(web): prevent StatusBar infinite render loop (React #185) - #1
Merged
Merged
Conversation
StatusBar derived a fresh ContextWindowSnapshot object inside the useStore selector, so zustand's useSyncExternalStore saw a changed reference on every render and triggered "Maximum update depth exceeded" (React error pingdotgg#185) whenever a thread with context data was opened. Split the selector into a useShallow selection of the stable source data (activity ids + activity map) and a useMemo that derives the snapshot only when those change. Also use stable module-level empty constants for the fallback branches so a freshly-opened thread with no activity yet cannot defeat useShallow's reference comparison and loop. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Opening a thread threw React error pingdotgg#185 ("Maximum update depth exceeded") — an infinite re-render loop. The desktop app's embedded server (port 3773) served the old bundle, so the loop fired on every affected build.
Root cause
StatusBarderived a freshContextWindowSnapshotobject inside theuseStoreselector. Each store read returned a new object reference, so zustand'suseSyncExternalStoresaw a changed value every render → infinite loop. It only triggered once a thread had context/token data to show.Fix
useShallow, then derive the snapshot inuseMemoso it recomputes only when the source changes.EMPTY_ACTIVITY_IDS/EMPTY_ACTIVITY_MAP) for the fallback branches, so a freshly-opened thread with no activity yet can't defeatuseShallow's reference comparison and re-loop.Also included
chore(desktop):neverBundle: ["electron"]in pack/preload config (pre-existing local change).Verification
apps/webrebuilt successfully (new bundleindex-CLBfhs73.js).apps/server/dist/client; the old broken bundle is gone.🤖 Generated with Claude Code