Skip to content
Open
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { recordStoreFamilyState } from '@/object-record/record-store/states/reco
import { dateLocaleState } from '~/localization/states/dateLocaleState';
import { beautifyPastDateRelativeToNow } from '~/utils/date-utils';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
import { allowRequestsToTwentyIconsState } from '@/client-config/states/allowRequestsToTwentyIcons';

const StyledTimelineItemContainer = styled.div`
color: ${({ theme }) => theme.font.color.primary};
Expand Down Expand Up @@ -92,6 +93,11 @@ export const EventRow = ({
mainObjectMetadataItem,
}: EventRowProps) => {
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);

const allowRequestsToTwentyIcons = useRecoilValue(
allowRequestsToTwentyIconsState,
);

const { localeCatalog } = useRecoilValue(dateLocaleState);

const { recordId } = useContext(TimelineActivityContext);
Expand Down Expand Up @@ -120,6 +126,7 @@ export const EventRow = ({
const labelIdentifier = getObjectRecordIdentifier({
objectMetadataItem: mainObjectMetadataItem,
record: recordFromStore,
allowRequestsToTwentyIcons,
});

const authorFullName = getTimelineActivityAuthorFullName(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { useCallback } from 'react';
import { useRecoilState, useSetRecoilState } from 'recoil';
import { clientConfigApiStatusState } from '@/client-config/states/clientConfigApiStatusState';
import { getClientConfig } from '@/client-config/utils/getClientConfig';
import { allowRequestsToTwentyIconsState } from '@/client-config/states/allowRequestsToTwentyIcons';

type UseClientConfigResult = {
data: { clientConfig: ClientConfig } | undefined;
Expand Down Expand Up @@ -110,6 +111,10 @@ export const useClientConfig = (): UseClientConfigResult => {
const setIsEmailingDomainsEnabled = useSetRecoilState(
isEmailingDomainsEnabledState,
);

const setAllowRequestsToTwentyIcons = useSetRecoilState(
allowRequestsToTwentyIconsState);

const setIsCloudflareIntegrationEnabled = useSetRecoilState(
isCloudflareIntegrationEnabledState,
);
Expand Down Expand Up @@ -188,6 +193,7 @@ export const useClientConfig = (): UseClientConfigResult => {
setCalendarBookingPageId(clientConfig?.calendarBookingPageId ?? null);
setIsImapSmtpCaldavEnabled(clientConfig?.isImapSmtpCaldavEnabled);
setIsEmailingDomainsEnabled(clientConfig?.isEmailingDomainsEnabled);
setAllowRequestsToTwentyIcons(clientConfig?.allowRequestsToTwentyIcons);
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Jan 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Missing default fallback for optional allowRequestsToTwentyIcons; undefined response overrides default true and disables icon requests with older servers

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/twenty-front/src/modules/client-config/hooks/useClientConfig.ts, line 191:

<comment>Missing default fallback for optional allowRequestsToTwentyIcons; undefined response overrides default true and disables icon requests with older servers</comment>

<file context>
@@ -184,6 +188,7 @@ export const useClientConfig = (): UseClientConfigResult => {
       setCalendarBookingPageId(clientConfig?.calendarBookingPageId ?? null);
       setIsImapSmtpCaldavEnabled(clientConfig?.isImapSmtpCaldavEnabled);
       setIsEmailingDomainsEnabled(clientConfig?.isEmailingDomainsEnabled);
+      setAllowRequestsToTwentyIcons(clientConfig?.allowRequestsToTwentyIcons);
     } catch (err) {
       const error =
</file context>
Suggested change
setAllowRequestsToTwentyIcons(clientConfig?.allowRequestsToTwentyIcons);
setAllowRequestsToTwentyIcons(
clientConfig?.allowRequestsToTwentyIcons ?? true,
);
Fix with Cubic

setIsCloudflareIntegrationEnabled(
clientConfig?.isCloudflareIntegrationEnabled,
);
Expand Down Expand Up @@ -230,6 +236,7 @@ export const useClientConfig = (): UseClientConfigResult => {
setMicrosoftMessagingEnabled,
setSentryConfig,
setSupportChat,
setAllowRequestsToTwentyIcons,
]);

return {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { createState } from 'twenty-ui/utilities';

export const allowRequestsToTwentyIconsState = createState<boolean>({
key: 'allowRequestsToTwentyIcons',
defaultValue: true,
});
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,5 @@ export type ClientConfig = {
signInPrefilled: boolean;
support: Support;
isTwoFactorAuthenticationEnabled: boolean;
allowRequestsToTwentyIcons: boolean;
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { CommandMenuContextRecordChipAvatars } from '@/command-menu/components/C
import { getSelectedRecordsContextText } from '@/command-menu/utils/getRecordContextText';
import { useFindManyRecordsSelectedInContextStore } from '@/context-store/hooks/useFindManyRecordsSelectedInContextStore';
import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMetadataItemById';
import { useRecoilValue } from 'recoil';
import { allowRequestsToTwentyIconsState } from '@/client-config/states/allowRequestsToTwentyIcons';

export const CommandMenuContextRecordsChip = ({
objectMetadataItemId,
Expand All @@ -14,6 +16,9 @@ export const CommandMenuContextRecordsChip = ({
const { objectMetadataItem } = useObjectMetadataItemById({
objectId: objectMetadataItemId,
});
const allowRequestsToTwentyIcons = useRecoilValue(
allowRequestsToTwentyIconsState,
);

const { records, loading, totalCount } =
useFindManyRecordsSelectedInContextStore({
Expand All @@ -39,6 +44,7 @@ export const CommandMenuContextRecordsChip = ({
objectMetadataItem,
records,
totalCount,
allowRequestsToTwentyIcons,
)}
Icons={Avatars}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { FieldMetadataType } from '~/generated-metadata/graphql';
import { dateLocaleState } from '~/localization/states/dateLocaleState';
import { beautifyPastDateRelativeToNow } from '~/utils/date-utils';
import { CommandMenuPageInfoLayout } from './CommandMenuPageInfoLayout';
import { allowRequestsToTwentyIconsState } from '@/client-config/states/allowRequestsToTwentyIcons';

export const CommandMenuRecordInfo = ({
commandMenuPageInstanceId,
Expand All @@ -29,6 +30,9 @@ export const CommandMenuRecordInfo = ({
viewableRecordNameSingularComponentState,
commandMenuPageInstanceId,
);
const allowRequestsToTwentyIcons = useRecoilValue(
allowRequestsToTwentyIconsState,
);

const viewableRecordId = useRecoilComponentValue(
viewableRecordIdComponentState,
Expand All @@ -50,6 +54,7 @@ export const CommandMenuRecordInfo = ({
const recordIdentifier = useRecoilValue(
recordStoreIdentifierFamilySelector({
recordId: objectRecordId,
allowRequestsToTwentyIcons,
}),
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import styled from '@emotion/styled';
import { useMemo } from 'react';
import { useRecoilValue } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
import { allowRequestsToTwentyIconsState } from '@/client-config/states/allowRequestsToTwentyIcons';

const StyledIconWrapper = styled.div`
background: ${({ theme }) => theme.background.primary};
Expand All @@ -25,6 +26,10 @@ export const useCommandMenuContextChips = () => {
commandMenuNavigationStackState,
);

const allowRequestsToTwentyIcons = useRecoilValue(
allowRequestsToTwentyIconsState,
);

const objectMetadataItems = useRecoilValue(objectMetadataItemsState);

const { navigateCommandMenuHistory } = useCommandMenuHistory();
Expand All @@ -44,6 +49,7 @@ export const useCommandMenuContextChips = () => {
const recordIdentifiers = useRecoilValue(
recordStoreIdentifiersFamilySelector({
recordIds: allRecordIds,
allowRequestsToTwentyIcons,
}),
);
const records = useRecoilValue(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@ export const getSelectedRecordsContextText = (
objectMetadataItem: ObjectMetadataItem,
records: ObjectRecord[],
totalCount: number,
allowRequestsToTwentyIcons: boolean,
) => {
return totalCount === 1
? getObjectRecordIdentifier({ objectMetadataItem, record: records[0] }).name
? getObjectRecordIdentifier({
objectMetadataItem,
record: records[0],
allowRequestsToTwentyIcons,
}).name
: `${totalCount} ${objectMetadataItem.labelPlural}`;
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useMemo } from 'react';
import { useRecoilValue } from 'recoil';
import { FieldMetadataType } from '~/generated-metadata/graphql';
import { usePrefetchedFavoritesData } from './usePrefetchedFavoritesData';
import { allowRequestsToTwentyIconsState } from '@/client-config/states/allowRequestsToTwentyIcons';

export const useFavorites = () => {
const { favorites } = usePrefetchedFavoritesData();
Expand All @@ -19,8 +20,11 @@ export const useFavorites = () => {
useObjectMetadataItem({
objectNameSingular: CoreObjectNameSingular.Favorite,
});
const allowRequestsToTwentyIcons = useRecoilValue(
allowRequestsToTwentyIconsState,
);
const getObjectRecordIdentifierByNameSingular =
useGetObjectRecordIdentifierByNameSingular();
useGetObjectRecordIdentifierByNameSingular(allowRequestsToTwentyIcons);

const favoriteRelationFieldMetadataItems = useMemo(
() =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadat
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useRecoilValue } from 'recoil';
import { FieldMetadataType } from '~/generated-metadata/graphql';
import { allowRequestsToTwentyIconsState } from '@/client-config/states/allowRequestsToTwentyIcons';

export const useFavoritesMetadata = () => {
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
const allowRequestsToTwentyIcons = useRecoilValue(
allowRequestsToTwentyIconsState,
);
const getObjectRecordIdentifierByNameSingular =
useGetObjectRecordIdentifierByNameSingular();
useGetObjectRecordIdentifierByNameSingular(allowRequestsToTwentyIcons);

const { objectMetadataItem: favoriteObjectMetadataItem } =
useObjectMetadataItem({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
FieldMetadataType,
} from '~/generated-metadata/graphql';
import { usePrefetchedFavoritesData } from './usePrefetchedFavoritesData';
import { allowRequestsToTwentyIconsState } from '@/client-config/states/allowRequestsToTwentyIcons';

export const useWorkspaceFavorites = () => {
const featureFlags = useFeatureFlagsMap();
Expand All @@ -24,8 +25,11 @@ export const useWorkspaceFavorites = () => {
useObjectMetadataItem({
objectNameSingular: CoreObjectNameSingular.Favorite,
});
const allowRequestsToTwentyIcons = useRecoilValue(
allowRequestsToTwentyIconsState,
);
const getObjectRecordIdentifierByNameSingular =
useGetObjectRecordIdentifierByNameSingular();
useGetObjectRecordIdentifierByNameSingular(allowRequestsToTwentyIcons);

const favoriteRelationFieldMetadataItems = useMemo(
() =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,22 @@ import { useRecoilValue } from 'recoil';
import { PreComputedChipGeneratorsContext } from '@/object-metadata/contexts/PreComputedChipGeneratorsContext';
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { getRecordChipGenerators } from '@/object-record/utils/getRecordChipGenerators';
import { allowRequestsToTwentyIconsState } from '@/client-config/states/allowRequestsToTwentyIcons';

export const PreComputedChipGeneratorsProvider = ({
children,
}: React.PropsWithChildren) => {
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);

const allowRequestsToTwentyIcons = useRecoilValue(
allowRequestsToTwentyIconsState,
);
const { chipGeneratorPerObjectPerField, identifierChipGeneratorPerObject } =
useMemo(() => {
return getRecordChipGenerators(objectMetadataItems);
}, [objectMetadataItems]);
return getRecordChipGenerators(
objectMetadataItems,
allowRequestsToTwentyIcons,
);
}, [allowRequestsToTwentyIcons, objectMetadataItems]);

return (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe('useGetObjectRecordIdentifierByNameSingular', () => {

setMetadataItems(generatedMockObjectMetadataItems);

return useGetObjectRecordIdentifierByNameSingular()(
return useGetObjectRecordIdentifierByNameSingular(true)(
record,
objectNameSingular,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ describe('useMapToObjectRecordIdentifier', () => {
() => {
const { mapToObjectRecordIdentifier } = useMapToObjectRecordIdentifier({
objectNameSingular: 'person',
allowRequestsToTwentyIcons: true,
});

return mapToObjectRecordIdentifier({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadat
import { getObjectRecordIdentifier } from '@/object-metadata/utils/getObjectRecordIdentifier';
import { type ObjectRecordIdentifier } from '@/object-record/types/ObjectRecordIdentifier';

export const useGetObjectRecordIdentifierByNameSingular = () => {
export const useGetObjectRecordIdentifierByNameSingular = (
allowRequestsToTwentyIcons: boolean,
) => {
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);

return (record: any, objectNameSingular: string): ObjectRecordIdentifier => {
Expand All @@ -21,6 +23,7 @@ export const useGetObjectRecordIdentifierByNameSingular = () => {
return getObjectRecordIdentifier({
objectMetadataItem,
record,
allowRequestsToTwentyIcons,
});
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,21 @@ import { type ObjectRecord } from '@/object-record/types/ObjectRecord';

export const useMapToObjectRecordIdentifier = ({
objectNameSingular,
allowRequestsToTwentyIcons,
}: {
objectNameSingular: string;
allowRequestsToTwentyIcons: boolean;
}) => {
const { objectMetadataItem } = useObjectMetadataItem({
objectNameSingular,
});

const mapToObjectRecordIdentifier = (record: ObjectRecord) => {
return getObjectRecordIdentifier({ objectMetadataItem, record });
return getObjectRecordIdentifier({
objectMetadataItem,
record,
allowRequestsToTwentyIcons,
});
};

return { mapToObjectRecordIdentifier };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@ export const getAvatarUrl = (
objectNameSingular: string,
record: ObjectRecord,
imageIdentifierFieldMetadataItem: FieldMetadataItem | undefined,
allowRequestsToTwentyIcons?: boolean | undefined,
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Jan 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Regression: new allowRequestsToTwentyIcons flag defaults to undefined, so existing calls now skip company logo URLs and return empty avatar for companies without image field

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/twenty-front/src/modules/object-metadata/utils/getAvatarUrl.ts, line 18:

<comment>Regression: new allowRequestsToTwentyIcons flag defaults to undefined, so existing calls now skip company logo URLs and return empty avatar for companies without image field</comment>

<file context>
@@ -15,12 +15,16 @@ export const getAvatarUrl = (
   objectNameSingular: string,
   record: ObjectRecord,
   imageIdentifierFieldMetadataItem: FieldMetadataItem | undefined,
+  allowRequestsToTwentyIcons?: boolean | undefined,
 ) => {
   if (objectNameSingular === CoreObjectNameSingular.WorkspaceMember) {
</file context>
Fix with Cubic

) => {
if (objectNameSingular === CoreObjectNameSingular.WorkspaceMember) {
return record.avatarUrl ?? undefined;
}

if (objectNameSingular === CoreObjectNameSingular.Company) {
if (
objectNameSingular === CoreObjectNameSingular.Company &&
allowRequestsToTwentyIcons === true
) {
return getLogoUrlFromDomainName(
getCompanyDomainName(record as Company) ?? '',
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { getLinkToShowPage } from './getLinkToShowPage';
export const getObjectRecordIdentifier = ({
objectMetadataItem,
record,
allowRequestsToTwentyIcons,
}: {
objectMetadataItem: Pick<
ObjectMetadataItem,
Expand All @@ -20,6 +21,7 @@ export const getObjectRecordIdentifier = ({
| 'imageIdentifierFieldMetadataId'
>;
record: ObjectRecord;
allowRequestsToTwentyIcons: boolean;
}): ObjectRecordIdentifier => {
const labelIdentifierFieldMetadataItem =
getLabelIdentifierFieldMetadataItem(objectMetadataItem);
Expand All @@ -40,6 +42,7 @@ export const getObjectRecordIdentifier = ({
objectMetadataItem.nameSingular,
record,
imageIdentifierFieldMetadata,
allowRequestsToTwentyIcons,
);

const linkToShowPage = getLinkToShowPage(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import {
jsonRelationFilterValueSchema,
} from 'twenty-shared/utils';
import { IconUserCircle } from 'twenty-ui/display';
import { useRecoilValue } from 'recoil';
import { allowRequestsToTwentyIconsState } from '@/client-config/states/allowRequestsToTwentyIcons';

export const EMPTY_FILTER_VALUE: string = JSON.stringify({
isCurrentWorkspaceMemberSelected: false,
Expand All @@ -41,6 +43,10 @@ export const ObjectFilterDropdownRecordSelect = ({
fieldMetadataItemUsedInDropdownComponentSelector,
);

const allowRequestsToTwentyIcons = useRecoilValue(
allowRequestsToTwentyIconsState,
);

const { objectFilterDropdownFilterValue } =
useObjectFilterDropdownFilterValue();

Expand Down Expand Up @@ -120,6 +126,7 @@ export const ObjectFilterDropdownRecordSelect = ({
selectedIds: selectedRecordIds,
objectNameSingular,
limit: 10,
allowRequestsToTwentyIcons,
});

const currentWorkspaceMemberSelectableItem: SelectableItem = {
Expand Down
Loading
Loading