From 256dbd7fc2e9feabb6f16c49575521e87f791de8 Mon Sep 17 00:00:00 2001 From: Sonarly Claude Code Date: Tue, 31 Mar 2026 08:56:58 +0000 Subject: [PATCH] Side panel crash from unguarded onTransitionEnd bubbling https://sonarly.com/issue/19891?type=bug SidePanelRecordPage throws "Record id is not defined" when a child CSS transitionend event bubbles to SidePanelForDesktop's onTransitionEnd handler, triggering premature state cleanup during the close animation and leaving the component with an empty instanceId context pointing to an unpopulated atom. --- .../side-panel/components/SidePanelForDesktop.tsx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/twenty-front/src/modules/side-panel/components/SidePanelForDesktop.tsx b/packages/twenty-front/src/modules/side-panel/components/SidePanelForDesktop.tsx index 004f092886a..75f518e75b3 100644 --- a/packages/twenty-front/src/modules/side-panel/components/SidePanelForDesktop.tsx +++ b/packages/twenty-front/src/modules/side-panel/components/SidePanelForDesktop.tsx @@ -18,7 +18,7 @@ import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState'; import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState'; import { styled } from '@linaria/react'; -import { useCallback, useState } from 'react'; +import { type TransitionEvent, useCallback, useState } from 'react'; import { themeCssVariables } from 'twenty-ui/theme-constants'; const StyledSidePanelWrapper = styled.div<{ @@ -81,7 +81,16 @@ export const SidePanelForDesktop = () => { const shouldShowContent = isSidePanelOpened || shouldRenderContent; - const handleTransitionEnd = () => { + const handleTransitionEnd = ( + event: TransitionEvent, + ) => { + if ( + event.target !== event.currentTarget || + event.propertyName !== 'width' + ) { + return; + } + if (isSidePanelOpened) { // Open animation completed - ensure content persists for close animation setShouldRenderContent(true);