URGENT FIX - Clear Corrupted LocalStorage & MongoDB
Critical fix required to clear corrupted sync queue and reset MongoDB data
๐จ URGENT: Clear Corrupted Data & Fix Sync
๐ฏ The Problem
The sync queue in localStorage is corrupted beyond auto-repair. The operations have all fields as undefined, which means the serialization/deserialization is failing.
Additionally, MongoDB is not being updated - universeIds: [] remains empty even after creating universes.
โ IMMEDIATE FIX REQUIRED
Step 1: Clear ALL Browser Data ๐งน
In BOTH browsers, open console and run:
// 1. Clear localStorage
localStorage.clear();
// 2. Clear IndexedDB
(async () => {
const dbs = await indexedDB.databases();
for (const db of dbs) {
indexedDB.deleteDatabase(db.name);
console.log(`โ
Deleted database: ${db.name}`);
}
console.log('โ
All IndexedDB databases cleared');
})();
// 3. Verify it's empty
console.log('localStorage items:', Object.keys(localStorage).length);
Step 2: Clear MongoDB Space Records ๐๏ธ
In MongoDB Atlas/Compass, delete these space documents:
// Delete BOTH of these spaces:
{ "_id": { "$oid": "69067c087ebb621cd9ff8c3f" } }
{ "_id": { "$oid": "6909075c33381d2fd1da604a" } }
Why? These spaces have universeIds: [] and outdated data. Fresh start needed.
Step 3: Reload Both Browsers ๐
CMD/CTRL + Shift + R (hard reload in both browsers)
๐ Root Cause Analysis
Issue #1: autoFlashState Serialization
The syncQueue uses autoFlashState which persists to localStorage:
private syncQueue = autoFlashState<SyncOperation[]>('sync-queue', []);
Problem: When complex objects with methods or circular references are serialized to localStorage, they can become corrupted:
// What gets saved (JSON.stringify)
localStorage.setItem('flash:sync-queue', JSON.stringify(operations));
// What gets loaded (JSON.parse)
const operations = JSON.parse(localStorage.getItem('flash:sync-queue'));
// Result: undefined fields if serialization fails!
Issue #2: Space Not Syncing to Backend
Looking at your MongoDB, both spaces show:
universeIds: []โ Empty!updatedAttimestamps are old
This means: The space updates are NOT reaching MongoDB!
Possible causes:
- Corrupted operations blocking the sync
- Space update operations being skipped
- Backend endpoint not receiving the update
๐ง Proposed Fix: Safer Queue Persistence
Option A: Use GgStorage Instead of autoFlashState
Change:
// Before (using autoFlashState - localStorage)
private syncQueue = autoFlashState<SyncOperation[]>('sync-queue', []);
// After (using GgStorage - IndexedDB with better serialization)
private syncQueue = signal<SyncOperation[]>([]);
async initialize(config: Partial<SyncConfig>) {
// Load queue from IndexedDB
const savedQueue = await this.storage.get<SyncOperation[]>('sync-queue');
if (savedQueue) {
this.syncQueue.set(savedQueue);
}
// ...
}
private async queueOperation(operation: SyncOperation): Promise<void> {
this.syncQueue.update(queue => [...queue, operation]);
// Persist to IndexedDB
await this.storage.put('sync-queue', this.syncQueue());
}
Benefits:
- โ IndexedDB handles complex objects better
- โ No localStorage 5MB limit
- โ Better serialization/deserialization
- โ Async, non-blocking
Option B: Add Validation After Deserialization
Add to autoCleanupCorruptedQueue():
private async autoCleanupCorruptedQueue(): Promise<void> {
try {
const queue = this.syncQueue();
// โ
NEW: Check if queue itself is corrupted
if (!Array.isArray(queue)) {
this.logger.warn('[SyncEngine] ๐จ Queue is not an array! Resetting...');
this.syncQueue.set([]);
return;
}
if (queue.length === 0) {
this.logger.debug('[SyncEngine] โ
Queue is empty');
return;
}
// โ
ENHANCED: Deep validation of each operation
const validOperations = queue.filter((op: any) => {
// Check if op is even an object
if (!op || typeof op !== 'object') {
this.logger.warn('[SyncEngine] ๐งน Removing non-object operation:', typeof op);
return false;
}
// Check required fields
const hasRequiredFields =
op.id &&
op.operation &&
op.entity &&
op.key;
if (!hasRequiredFields) {
this.logger.warn('[SyncEngine] ๐งน Removing operation with undefined fields:', {
id: op.id || 'undefined',
operation: op.operation || 'undefined',
entity: op.entity || 'undefined',
key: op.key || 'undefined'
});
return false;
}
// โ
NEW: Validate data field for entities that require it
if (op.entity === 'universe' && op.operation !== 'delete') {
if (!op.data || typeof op.data !== 'object') {
this.logger.warn('[SyncEngine] ๐งน Removing universe operation without data');
return false;
}
}
return true;
});
const removedCount = queue.length - validOperations.length;
if (removedCount > 0) {
this.syncQueue.set(validOperations);
// โ
PERSIST to localStorage after cleanup
this.logger.warn(`[SyncEngine] ๐งน Auto-cleaned ${removedCount} corrupted operations`);
}
} catch (error) {
this.logger.error('[SyncEngine] Critical error in cleanup:', error);
this.syncQueue.set([]);
}
}
๐งช Testing After Fix
Step 1: Verify Clean Start
Console should show:
[SyncEngine] โ
Queue is empty
[SyncEngine] ๐ Starting sync...
[SpaceApiService] Getting current user space
[SpaceApiService] โ
Space loaded: chrome-space-1
[SyncEngine] โ
Backend space saved locally (first sync)
[SyncEngine] โ
Sync complete
Step 2: Create Universe
- Click "Create Universe"
- Name it "test-universe-1"
- Wait 5 seconds
Console should show:
[SpaceService] โก Universe created (offline-first): universe_1234567890
[SpaceService] โก Space updated with new universe: space_xxxxx
[SyncEngine] Queued operation: update universe_1234567890
[SyncEngine] Queued operation: update space_xxxxx
[SyncEngine] ๐ Starting sync...
[SyncEngine] ๐ค Pushing 2 operations to backend
[SyncEngine] ๐ Syncing operation: create universe universe_1234567890
[SpaceApiService] Creating universe: test-universe-1
[SpaceApiService] โ
Universe created: universe_1234567890
[SyncEngine] โ
Universe created in backend
[SyncEngine] ๐ Syncing operation: update space space_xxxxx
[SpaceApiService] Updating space: space_xxxxx
[SpaceApiService] โ
Space updated
[SyncEngine] โ
Space synced to backend
[SyncEngine] โ
Sync complete
Step 3: Verify MongoDB
Check MongoDB - space document should now show:
{
"_id": { "$oid": "..." },
"universeIds": ["universe_1234567890"], โ NOT EMPTY!
"updatedAt": "2025-11-17T...", โ NEW timestamp!
...
}
๐ Expected Results
| Check | Before | After |
|---|---|---|
| Console errors | โ Many | โ None |
| Sync queue | โ Corrupted | โ Clean |
| MongoDB universeIds | โ Empty [] |
โ Has IDs |
| MongoDB updatedAt | โ Old | โ Current |
| Multi-browser | โ Different | โ Same |
๐ Next Steps
- USER: Clear browser data & MongoDB (steps above)
- USER: Hard reload both browsers
- USER: Create a test universe
- USER: Share console output & MongoDB data
- AI: Verify fix worked or implement Option A (GgStorage)
๐ก Why This Happened
- autoFlashState uses localStorage
- localStorage only stores strings (JSON.stringify)
- Complex objects with functions/symbols get corrupted
- Corrupted queue blocks all syncs
- MongoDB never updates because syncs fail
Solution: Either clear data or migrate to IndexedDB (GgStorage)
โ ๏ธ CRITICAL
DO NOT PROCEED without clearing corrupted data first!
The system cannot self-heal from this level of corruption because the queue itself is malformed at the storage level.