Deleted Universe Cleanup Fix
Automatic removal of deleted universe IDs from space.universeIds
๐งน Deleted Universe Cleanup Fix
๐ The Problem
When a universe is deleted in one browser, other browsers continue trying to load it because the universe ID remains in the space.universeIds array. This causes persistent "Universe not found" errors in the backend logs.
Example:
[SpaceDatabaseService] โ Universe not found: universe_1763559265566
๐ Root Cause
The deletion flow was incomplete:
- Browser 1 deletes universe โ Removes from local storage & backend
- Browser 1 updates
space.universeIdslocally - Problem: Browser 2 doesn't know the universe was deleted
- Browser 2 keeps trying to load the deleted universe ID
โ The Solution
Added automatic cleanup of deleted universe IDs in two places:
1. In SpaceService loadUniverses():
When fetching a universe returns 404 after all retries, we now:
- Recognize it as deleted (not just "not synced yet")
- Remove the ID from
space.universeIds - Update local storage and signals
- Log the cleanup action
// After all retries exhausted with 404 error
if (remoteError?.status === 404) {
this.logger.error('[SpaceService] ๐ป Universe not found after retries - it was deleted');
// Remove deleted universe ID from space.universeIds
space.universeIds = space.universeIds.filter(id => id !== universeId);
space.updatedAt = new Date().toISOString();
// Update storage and signal
await this.syncEngine.write(`space_${space.ownerId}`, space, 'space');
this._currentSpace.set(space);
}
2. In SyncEngine pullFromBackend():
When pulling updates from backend, if a universe doesn't exist:
- Remove it from local storage
- Remove its layout data
- Log the cleanup
if (!backendUniverse) {
this.logger.warn('[SyncEngine] โ ๏ธ Universe not found on backend (was deleted)');
// Remove from local storage
if (localUniverse) {
await this.storage.remove(universeKey);
await this.storage.remove(layoutKey); // Also remove layout
this.logger.info('[SyncEngine] ๐งน Removed deleted universe from local storage');
}
continue;
}
๐ How It Works Now
Deletion Flow:
Browser 1: Delete universe
โ
Backend: Universe removed from MongoDB
โ
Browser 1: Updates space.universeIds locally
โ
Browser 2: Tries to load universe โ 404
โ
Browser 2: After retries โ Recognizes deletion
โ
Browser 2: Removes ID from space.universeIds
โ
No more "Universe not found" errors! โ
๐ Benefits
- Self-healing: Deleted universe IDs are automatically cleaned up
- No manual intervention: Works transparently in background
- Cross-browser consistency: All browsers eventually converge
- Clean logs: No more persistent 404 errors
- Better UX: Users don't see deleted universes
๐ฏ Key Improvements
Before:
- Deleted universe IDs persisted in
space.universeIds - Constant 404 errors in logs
- Manual refresh didn't help
- Required database cleanup
After:
- Automatic cleanup on 404 (after retries)
- Clean logs
- Self-healing data consistency
- No manual intervention needed
๐ง Implementation Details
Retry Logic:
- 3 attempts with exponential backoff (1s, 2s, 4s)
- Only 404 errors trigger cleanup (after all retries)
- Other errors don't remove universe IDs
Cleanup Scope:
- Universe data in IndexedDB
- Layout data for grid-canvas
- Universe ID from space.universeIds array
- Local state signals
Sync Propagation:
- Local cleanup triggers sync to backend
- Other browsers get updated space via pull
- Eventually consistent across all browsers
Created: November 19, 2025 - 3:30 PM
Session: 11.25.3.1
Status: Implemented
Priority: High (data consistency)