From f8db73598c15020e53051c1ba047b1842a9d99cc Mon Sep 17 00:00:00 2001 From: Weiko Date: Sun, 21 Jun 2026 17:26:41 +0200 Subject: [PATCH] Fix dangling relation fields crashing records after deleting a custom object (#21874) Fixes https://github.com/twentyhq/twenty/issues/21706 ## Context Deleting a custom object that has relation/junction fields pointing to it (e.g. a junction object linked from Person and Company) crashes record pages with `Target object metadata item not found for `. The backend cascade correctly deletes the related relation fields, view fields and page-layout widgets, but the frontend metadata store only removed the deleted object itself, leaving dangling relation fields (and stale UI-layer references) behind. ## Fix After a successful deletion, `useDeleteOneObjectMetadataItem` now calls `invalidateMetadataStore()`, triggering the existing reconcile path that refetches objects, fields, indexes, views, view fields and page-layout widgets. This removes the dangling relations and cleans up the UI layers in one consistent pass (also replacing the previous manual command-menu refetch). Review in cubic --- .../hooks/useDeleteOneObjectMetadataItem.ts | 24 +++++-------------- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/useDeleteOneObjectMetadataItem.ts b/packages/twenty-front/src/modules/object-metadata/hooks/useDeleteOneObjectMetadataItem.ts index 4e56bb02a7..601778ea0a 100644 --- a/packages/twenty-front/src/modules/object-metadata/hooks/useDeleteOneObjectMetadataItem.ts +++ b/packages/twenty-front/src/modules/object-metadata/hooks/useDeleteOneObjectMetadataItem.ts @@ -1,9 +1,7 @@ -import { useApolloClient, useMutation } from '@apollo/client/react'; -import { - DeleteOneObjectMetadataItemDocument, - FindManyCommandMenuItemsDocument, -} from '~/generated-metadata/graphql'; +import { useMutation } from '@apollo/client/react'; +import { DeleteOneObjectMetadataItemDocument } from '~/generated-metadata/graphql'; +import { useInvalidateMetadataStore } from '@/metadata-store/hooks/useInvalidateMetadataStore'; import { useMetadataErrorHandler } from '@/metadata-error-handler/hooks/useMetadataErrorHandler'; import { useUpdateMetadataStoreDraft } from '@/metadata-store/hooks/useUpdateMetadataStoreDraft'; import { type MetadataRequestResult } from '@/object-metadata/types/MetadataRequestResult.type'; @@ -17,11 +15,10 @@ export const useDeleteOneObjectMetadataItem = () => { DeleteOneObjectMetadataItemDocument, ); - const client = useApolloClient(); const { handleMetadataError } = useMetadataErrorHandler(); const { enqueueErrorSnackBar } = useSnackBar(); - const { removeFromDraft, replaceDraft, applyChanges } = - useUpdateMetadataStoreDraft(); + const { removeFromDraft, applyChanges } = useUpdateMetadataStoreDraft(); + const { invalidateMetadataStore } = useInvalidateMetadataStore(); const deleteOneObjectMetadataItem = async ( idToDelete: string, @@ -40,16 +37,7 @@ export const useDeleteOneObjectMetadataItem = () => { removeFromDraft({ key: 'objectMetadataItems', itemIds: [idToDelete] }); applyChanges(); - const commandMenuItemsResult = await client.query({ - query: FindManyCommandMenuItemsDocument, - fetchPolicy: 'network-only', - }); - - replaceDraft( - 'commandMenuItems', - commandMenuItemsResult.data?.commandMenuItems ?? [], - ); - applyChanges(); + invalidateMetadataStore(); return { status: 'successful',