From 1256331aa67b31e9a1e61ef2b6057f70a3accaf1 Mon Sep 17 00:00:00 2001 From: Anton Date: Wed, 3 Jun 2026 11:28:46 -0700 Subject: [PATCH] fix(editor): guard onShelfMove against null cursorGroupRef (#342) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the missing `if (!cursorGroupRef.current) return` guard to onShelfMove. mitt listeners are registered for the tool's whole lifetime, so a shelf event can fire before the cursor group mounts or after teardown, leaving the ref null and throwing on `cursorGroupRef.current.rotation.y`. Partial fix for the EDITOR-BC family: the other placement handlers (onGridMove/onWallMove/onItemMove/onCeilingMove and the keyboard/cancel paths) share the same null-ref exposure and still need the broader, correctly-scoped guard — tracked separately (PR #323 attempts this but needs rework). --- .../src/components/tools/item/use-placement-coordinator.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/editor/src/components/tools/item/use-placement-coordinator.tsx b/packages/editor/src/components/tools/item/use-placement-coordinator.tsx index 7dc4ccff..de204d5f 100644 --- a/packages/editor/src/components/tools/item/use-placement-coordinator.tsx +++ b/packages/editor/src/components/tools/item/use-placement-coordinator.tsx @@ -1147,6 +1147,9 @@ export function usePlacementCoordinator(config: PlacementCoordinatorConfig): Rea const onShelfMove = (event: ShelfEvent) => { has3DPointerDrivenMoveRef.current = true + // A shelf event can fire before the cursor group mounts or after + // teardown, leaving the ref null; bail before dereferencing it below. + if (!cursorGroupRef.current) return const ctx = getContext() if (ctx.state.surface !== 'shelf-surface') { // Cursor entered via a move event without an enter — try