Skip to content

Commit 4eeba9e

Browse files
committed
Fix: Add storesSynced state to prevent render before sync
Problem: syncWorkspaces runs in useEffect AFTER render, but sidebar components access the store DURING render, causing assertion failures. Solution: Add storesSynced state that only becomes true after syncWorkspaces completes. Gate UI rendering on both metadataLoading AND storesSynced to ensure stores are ready before any component tries to access them.
1 parent 2b1e9fa commit 4eeba9e

File tree

1 file changed

+10
-8
lines changed

1 file changed

+10
-8
lines changed

src/App.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -114,24 +114,26 @@ function AppInner() {
114114
const workspaceStore = useWorkspaceStoreRaw();
115115
const gitStatusStore = useGitStatusStoreRaw();
116116

117+
// Track whether stores have been synced (separate from metadata loading)
118+
const [storesSynced, setStoresSynced] = useState(false);
119+
117120
useEffect(() => {
118121
if (!metadataLoading) {
119122
workspaceStore.syncWorkspaces(workspaceMetadata);
120123
gitStatusStore.syncWorkspaces(workspaceMetadata);
124+
setStoresSynced(true);
125+
} else {
126+
setStoresSynced(false);
121127
}
122128
}, [metadataLoading, workspaceMetadata, workspaceStore, gitStatusStore]);
123129

124130
// Validate selectedWorkspace when metadata changes
125131
// Clear selection if workspace was deleted
126132
useEffect(() => {
127-
if (
128-
!metadataLoading &&
129-
selectedWorkspace &&
130-
!workspaceMetadata.has(selectedWorkspace.workspaceId)
131-
) {
133+
if (storesSynced && selectedWorkspace && !workspaceMetadata.has(selectedWorkspace.workspaceId)) {
132134
setSelectedWorkspace(null);
133135
}
134-
}, [metadataLoading, selectedWorkspace, workspaceMetadata, setSelectedWorkspace]);
136+
}, [storesSynced, selectedWorkspace, workspaceMetadata, setSelectedWorkspace]);
135137

136138
// Track last-read timestamps for unread indicators
137139
const { lastReadTimestamps, onToggleUnread } = useUnreadTracking(selectedWorkspace);
@@ -672,9 +674,9 @@ function AppInner() {
672674
);
673675
}, [projects, setSelectedWorkspace, setWorkspaceMetadata]);
674676

675-
// CRITICAL: Don't render workspace UI until metadata loads and stores are synced
677+
// CRITICAL: Don't render workspace UI until metadata loads AND stores are synced
676678
// This ensures WorkspaceStore.addWorkspace() is called before any component accesses workspaces
677-
if (metadataLoading) {
679+
if (metadataLoading || !storesSynced) {
678680
return <LoadingScreen />;
679681
}
680682

0 commit comments

Comments
 (0)