From cd2fe9d8ac171e98c7450b51c0ba773c918b6bfa Mon Sep 17 00:00:00 2001 From: Sonarly Claude Code Date: Thu, 23 Apr 2026 10:15:42 +0000 Subject: [PATCH] fix: restore fallback in useRecordChipData when identifier chip generator is missing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://sonarly.com/issue/30221?type=bug Commit 98e199c01dd ("Support Full Name as Record Text Identifier", PR #11610) removed the safe `generateDefaultRecordChipData` fallback in `useRecordChipData` and replaced it with a hard `throw new Error(...)`. When any custom object (here `educationProfile`) lacks a pre-computed identifier chip generator — because its `labelIdentifierFieldMetadataId` is null and it has no field named `name` — the throw crashes the React render tree. The generator is built in `getRecordChipGenerators` (line 109): generators are only registered when `getLabelIdentifierFieldMetadataItem` returns a defined value. For a custom object whose `labelIdentifierFieldMetadataId` is null in the DB (it is nullable per `object-metadata.entity.ts` line 101) and that has no field literally named `name`, no generator is registered. Before the regression commit, `useRecordChipData` gracefully fell back to `generateDefaultRecordChipData`; after the commit, it throws. Notably, the sister hooks `useRelationFromManyFieldDisplay` (line 60-67) and `useRelationToOneFieldDisplay` (line 71-78) still use `generateDefaultRecordChipData` as a fallback for the same missing-generator scenario, proving the codebase already acknowledges this as an expected edge case. Fix: Restored the `generateDefaultRecordChipData` fallback in `useRecordChipData` that was removed by commit 98e199c01dd ("Support Full Name as Record Text Identifier", PR #11610). The change replaces the hard `throw new Error(...)` with a graceful fallback to `generateDefaultRecordChipData` when no pre-computed identifier chip generator exists for a given object. This handles custom objects (like `educationProfile`) that lack a `labelIdentifierFieldMetadataId` and have no field named `name`. This is the same fallback pattern already used in `useRelationFromManyFieldDisplay` (lines 60-67) and `useRelationToOneFieldDisplay` (lines 71-78), confirming it is the intended approach for handling missing generators. The fix is a single-file change that only modifies `useRecordChipData.ts`, with no impact on the 2 callers since the return type remains `{ recordChipData: RecordChipData }`. --- .../object-record/hooks/useRecordChipData.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/twenty-front/src/modules/object-record/hooks/useRecordChipData.ts b/packages/twenty-front/src/modules/object-record/hooks/useRecordChipData.ts index 85747e428e8..cf054158934 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useRecordChipData.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useRecordChipData.ts @@ -1,4 +1,5 @@ import { PreComputedChipGeneratorsContext } from '@/object-metadata/contexts/PreComputedChipGeneratorsContext'; +import { generateDefaultRecordChipData } from '@/object-metadata/utils/generateDefaultRecordChipData'; import { type RecordChipData } from '@/object-record/record-field/ui/types/RecordChipData'; import { type ObjectRecord } from '@/object-record/types/ObjectRecord'; import { useContext } from 'react'; @@ -22,13 +23,16 @@ export const useRecordChipData = ({ const identifierChipGenerator = identifierChipGeneratorPerObject[objectNameSingular]; - if (!isDefined(identifierChipGenerator)) { - throw new Error( - `No identifier chip generator found for object name singular: ${objectNameSingular}`, - ); + if (isDefined(identifierChipGenerator)) { + return { + recordChipData: identifierChipGenerator(record), + }; } return { - recordChipData: identifierChipGenerator(record), + recordChipData: generateDefaultRecordChipData({ + objectNameSingular, + record, + }), }; };