| Throw "No handler registered for command type: X" | v2 file not in v2HandlerOverrides/v2Commands, or type string mismatch with the command union | register in src/core/cqrs/v2/registry.ts; strings must match exactly |
| Invalid payload reaches handler, no validation error | schema only in the inert v2 def; validation middleware passes unknown types through | add to COMMAND_SCHEMAS + ALL_COMMAND_TYPES |
| Ctrl+Z doesn't revert (or reverts too much) | profile isn't domain; or dispatched with source replay/cascade/collab; or inside someone else's batch() | fix COMMAND_PROFILES; dispatch user actions with default source |
| Boot crash "undefined is not a function", often production-only | imported function called at store module init (#1466 chunk cycle) | pure-literal placeholder state; defer imported calls |
| "Maximum update depth exceeded" / frozen UI | selector returns fresh object/array without useShallow — Zustand 5 + React 19 makes this an infinite loop, and it's convention-only, not lint-enforced | useShallow from zustand/react/shallow, or select primitives |
| Undo restores layout but selection/active layer jumps | stale IDs pruned; fallback active layer is layers[layers.length - 1] (top in UI — layers[0] is bottom) | expected behavior lives in restoreHandlers.ts; preserve it |
| "[migrations] Missing migration X v1→v2" | version bumped without registering every chain step | registerMigration per step; readers tolerate old versions |
| cloudShare metadata lost after reload | useAutoSave (1s debounce, keyed to layout changes, skips SHARED_PREVIEW_ID) never fires for library-only mutations | emit an event src/core/cqrs/subscribers/libraryPersistence.ts handles, or add a subscription there |
Events missing from gridfinity-events-db | by design: retry exhaustion, eviction, or mutation bypassed the bus (Liveblocks collab applies via importLayout, no events/analytics) | never treat the event store as truth; guaranteed persistence goes through saveLayoutWithMetadata |
| Undo history bleeds across layouts | a layout-activation path skipped clearHistory() | use src/shared/hooks/useLayoutActivation.ts: importLayout → clearSelection → setActiveLayer → setActiveCategory → clearHistory |