From 761c717b750b57d61e6c4e2c0c2ec614c1c7b991 Mon Sep 17 00:00:00 2001 From: Pedro Figueiredo Date: Wed, 27 May 2026 14:23:43 +0100 Subject: [PATCH 1/5] fix: Normalize remote feature flag value wrappers --- .../CHANGELOG.md | 4 + .../remote-feature-flag-controller-types.ts | 4 +- .../remote-feature-flag-controller.test.ts | 202 ++++++++++++++++++ .../src/remote-feature-flag-controller.ts | 62 +++++- 4 files changed, 266 insertions(+), 6 deletions(-) diff --git a/packages/remote-feature-flag-controller/CHANGELOG.md b/packages/remote-feature-flag-controller/CHANGELOG.md index 0b7be74d54..36612eed26 100644 --- a/packages/remote-feature-flag-controller/CHANGELOG.md +++ b/packages/remote-feature-flag-controller/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Bump `@metamask/controller-utils` from `^12.0.0` to `^12.1.0` ([#8774](https://github.com/MetaMask/core/pull/8774)) +### Fixed + +- Normalize object-valued feature flag wrappers so `value` contents of threshold entries are exposed at the top level while preserving the `value` property when expected by older selectors ([#8908](https://github.com/MetaMask/core/pull/8908)) + ## [4.2.1] ### Changed diff --git a/packages/remote-feature-flag-controller/src/remote-feature-flag-controller-types.ts b/packages/remote-feature-flag-controller/src/remote-feature-flag-controller-types.ts index 6bf8e5ea2f..dd120e1871 100644 --- a/packages/remote-feature-flag-controller/src/remote-feature-flag-controller-types.ts +++ b/packages/remote-feature-flag-controller/src/remote-feature-flag-controller-types.ts @@ -40,7 +40,9 @@ export type FeatureFlagScope = { }; export type FeatureFlagScopeValue = { - name: string; + name?: string; + thresholdName?: string; + thresholdVersion?: number; scope: FeatureFlagScope; value: Json; }; diff --git a/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.test.ts b/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.test.ts index 142995b345..4516629a7d 100644 --- a/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.test.ts +++ b/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.test.ts @@ -425,6 +425,31 @@ describe('RemoteFeatureFlagController', () => { }); }); + describe('feature flag value normalization', () => { + it('preserves direct feature flag config objects without value metadata', async () => { + const directConfig = { + enabled: true, + minimumVersion: '13.10.0', + }; + const clientConfigApiService = buildClientConfigApiService({ + remoteFeatureFlags: { + directConfig, + }, + }); + const { controller, messenger } = createController({ + clientConfigApiService, + }); + + await messenger.call( + 'RemoteFeatureFlagController:updateRemoteFeatureFlags', + ); + + expect(controller.state.remoteFeatureFlags.directConfig).toStrictEqual( + directConfig, + ); + }); + }); + describe('threshold feature flags', () => { it('processes threshold feature flags based on provided metaMetricsId', async () => { const clientConfigApiService = buildClientConfigApiService({ @@ -448,6 +473,109 @@ describe('RemoteFeatureFlagController', () => { }); }); + it('spreads selected threshold object values while preserving the value property', async () => { + const thresholdFlagValue = { + enabled: true, + minimumVersion: '13.10.0', + attemptsMax: 5, + }; + const mockFlags = { + thresholdObjectFlag: [ + { + name: 'enabled', + scope: { type: 'threshold', value: 1.0 }, + value: thresholdFlagValue, + }, + ], + }; + const clientConfigApiService = buildClientConfigApiService({ + remoteFeatureFlags: mockFlags, + }); + const { controller, messenger } = createController({ + clientConfigApiService, + getMetaMetricsId: () => MOCK_METRICS_ID, + }); + + await messenger.call( + 'RemoteFeatureFlagController:updateRemoteFeatureFlags', + ); + + expect( + controller.state.remoteFeatureFlags.thresholdObjectFlag, + ).toStrictEqual({ + name: 'enabled', + enabled: true, + minimumVersion: '13.10.0', + attemptsMax: 5, + value: thresholdFlagValue, + }); + }); + + it('returns selected threshold version 2 values without wrapper metadata', async () => { + const thresholdFlagValue = { + enabled: true, + minimumVersion: '13.10.0', + attemptsMax: 5, + }; + const mockFlags = { + thresholdObjectFlag: [ + { + thresholdName: 'enabled', + thresholdVersion: 2, + scope: { type: 'threshold', value: 1.0 }, + value: thresholdFlagValue, + }, + ], + }; + const clientConfigApiService = buildClientConfigApiService({ + remoteFeatureFlags: mockFlags, + }); + const { controller, messenger } = createController({ + clientConfigApiService, + getMetaMetricsId: () => MOCK_METRICS_ID, + }); + + await messenger.call( + 'RemoteFeatureFlagController:updateRemoteFeatureFlags', + ); + + expect( + controller.state.remoteFeatureFlags.thresholdObjectFlag, + ).toStrictEqual(thresholdFlagValue); + }); + + it('omits selected threshold name when no name metadata is configured', async () => { + const thresholdFlagValue = { + enabled: true, + }; + const mockFlags = { + thresholdObjectFlag: [ + { + scope: { type: 'threshold', value: 1.0 }, + value: thresholdFlagValue, + }, + ], + }; + const clientConfigApiService = buildClientConfigApiService({ + remoteFeatureFlags: mockFlags, + }); + const { controller, messenger } = createController({ + clientConfigApiService, + getMetaMetricsId: () => MOCK_METRICS_ID, + }); + + await messenger.call( + 'RemoteFeatureFlagController:updateRemoteFeatureFlags', + ); + + expect( + controller.state.remoteFeatureFlags.thresholdObjectFlag, + ).toStrictEqual({ + enabled: true, + value: thresholdFlagValue, + }); + }); + it('preserves non-threshold feature flags unchanged', async () => { const clientConfigApiService = buildClientConfigApiService({ remoteFeatureFlags: MOCK_FLAGS_WITH_THRESHOLD, @@ -934,10 +1062,84 @@ describe('RemoteFeatureFlagController', () => { // Threshold = 0.094878, which falls in groupA range (t <= 0.3) expect(multiVersionABFlag).toStrictEqual({ name: 'groupA', + feature: 'A', + enabled: true, value: { feature: 'A', enabled: true }, }); expect(regularFlag).toBe(true); }); + + it('spreads selected multi-version object values while preserving the value property', async () => { + const mockApiService = buildClientConfigApiService(); + const versionedFlagValue = { + enabled: true, + slippage: 0.5, + }; + const mockFlags = { + multiVersionWrappedFlag: { + versions: { + '13.1.0': { + value: versionedFlagValue, + }, + }, + }, + }; + + jest.spyOn(mockApiService, 'fetchRemoteFeatureFlags').mockResolvedValue({ + remoteFeatureFlags: mockFlags, + cacheTimestamp: Date.now(), + }); + + const { controller, messenger } = createController({ + clientConfigApiService: mockApiService, + clientVersion: '13.1.5', + }); + + await messenger.call( + 'RemoteFeatureFlagController:updateRemoteFeatureFlags', + ); + + expect( + controller.state.remoteFeatureFlags.multiVersionWrappedFlag, + ).toStrictEqual({ + enabled: true, + slippage: 0.5, + value: versionedFlagValue, + }); + }); + + it('preserves selected multi-version primitive value wrappers', async () => { + const mockApiService = buildClientConfigApiService(); + const mockFlags = { + multiVersionWrappedFlag: { + versions: { + '13.1.0': { + value: true, + }, + }, + }, + }; + + jest.spyOn(mockApiService, 'fetchRemoteFeatureFlags').mockResolvedValue({ + remoteFeatureFlags: mockFlags, + cacheTimestamp: Date.now(), + }); + + const { controller, messenger } = createController({ + clientConfigApiService: mockApiService, + clientVersion: '13.1.5', + }); + + await messenger.call( + 'RemoteFeatureFlagController:updateRemoteFeatureFlags', + ); + + expect( + controller.state.remoteFeatureFlags.multiVersionWrappedFlag, + ).toStrictEqual({ + value: true, + }); + }); }); describe('getDefaultRemoteFeatureFlagControllerState', () => { diff --git a/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts b/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts index 8f8fbbb4db..1b7a9c160a 100644 --- a/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts +++ b/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts @@ -24,6 +24,13 @@ import { isVersionFeatureFlag, getVersionData } from './utils/version'; export const controllerName = 'RemoteFeatureFlagController'; export const DEFAULT_CACHE_DURATION = 24 * 60 * 60 * 1000; // 1 day +const THRESHOLD_VALUE_VERSION = 2; + +type JsonObject = Record; + +type FeatureFlagValueWrapper = JsonObject & { + value: Json; +}; // === STATE === @@ -118,6 +125,45 @@ export function getDefaultRemoteFeatureFlagControllerState(): RemoteFeatureFlagC }; } +function isJsonObject(value: Json): value is JsonObject { + return typeof value === 'object' && value !== null && !Array.isArray(value); +} + +function isFeatureFlagValueWrapper( + value: Json, +): value is FeatureFlagValueWrapper { + return ( + isJsonObject(value) && Object.prototype.hasOwnProperty.call(value, 'value') + ); +} + +function spreadFeatureFlagValueWrapper( + featureFlagValue: FeatureFlagValueWrapper, +): Json { + if (!isJsonObject(featureFlagValue.value)) { + return featureFlagValue; + } + + return { + ...featureFlagValue, + ...featureFlagValue.value, + }; +} + +function normalizeThresholdValue(featureFlag: FeatureFlagScopeValue): Json { + if (featureFlag.thresholdVersion === THRESHOLD_VALUE_VERSION) { + return featureFlag.value; + } + + const name = featureFlag.thresholdName ?? featureFlag.name; + + return { + ...(isJsonObject(featureFlag.value) ? featureFlag.value : {}), + ...(name === undefined ? {} : { name }), + value: featureFlag.value, + }; +} + /** * The RemoteFeatureFlagController manages the retrieval and caching of remote feature flags. * It fetches feature flags from a remote API, caches them, and provides methods to access @@ -306,7 +352,15 @@ export class RemoteFeatureFlagController extends BaseController< return flagValue; } - return getVersionData(flagValue, this.#clientVersion); + const versionData = getVersionData(flagValue, this.#clientVersion); + + if (versionData === null) { + return null; + } + + return isFeatureFlagValueWrapper(versionData) + ? spreadFeatureFlagValueWrapper(versionData) + : versionData; } async #processRemoteFeatureFlags(remoteFeatureFlags: FeatureFlags): Promise<{ @@ -371,11 +425,9 @@ export class RemoteFeatureFlagController extends BaseController< return threshold <= featureFlag.scope.value; }, ); + if (selectedGroup) { - processedValue = { - name: selectedGroup.name, - value: selectedGroup.value, - }; + processedValue = normalizeThresholdValue(selectedGroup); } } From 4b6e1ccbcc3f73522ae9153fe9321d0b03619382 Mon Sep 17 00:00:00 2001 From: Pedro Figueiredo Date: Thu, 28 May 2026 14:28:03 +0100 Subject: [PATCH 2/5] Remove unsupported version flag wrapper normalization --- .../CHANGELOG.md | 2 +- .../remote-feature-flag-controller.test.ts | 72 ------------------- .../src/remote-feature-flag-controller.ts | 29 +------- 3 files changed, 2 insertions(+), 101 deletions(-) diff --git a/packages/remote-feature-flag-controller/CHANGELOG.md b/packages/remote-feature-flag-controller/CHANGELOG.md index 36612eed26..e16c29af7d 100644 --- a/packages/remote-feature-flag-controller/CHANGELOG.md +++ b/packages/remote-feature-flag-controller/CHANGELOG.md @@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -- Normalize object-valued feature flag wrappers so `value` contents of threshold entries are exposed at the top level while preserving the `value` property when expected by older selectors ([#8908](https://github.com/MetaMask/core/pull/8908)) +- Normalize object-valued threshold feature flag entries so `value` contents are exposed at the top level while preserving the `value` property, and support `thresholdVersion: 2` entries that return the selected `value` directly ([#8908](https://github.com/MetaMask/core/pull/8908)) ## [4.2.1] diff --git a/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.test.ts b/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.test.ts index 4516629a7d..385fbf6b7b 100644 --- a/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.test.ts +++ b/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.test.ts @@ -1068,78 +1068,6 @@ describe('RemoteFeatureFlagController', () => { }); expect(regularFlag).toBe(true); }); - - it('spreads selected multi-version object values while preserving the value property', async () => { - const mockApiService = buildClientConfigApiService(); - const versionedFlagValue = { - enabled: true, - slippage: 0.5, - }; - const mockFlags = { - multiVersionWrappedFlag: { - versions: { - '13.1.0': { - value: versionedFlagValue, - }, - }, - }, - }; - - jest.spyOn(mockApiService, 'fetchRemoteFeatureFlags').mockResolvedValue({ - remoteFeatureFlags: mockFlags, - cacheTimestamp: Date.now(), - }); - - const { controller, messenger } = createController({ - clientConfigApiService: mockApiService, - clientVersion: '13.1.5', - }); - - await messenger.call( - 'RemoteFeatureFlagController:updateRemoteFeatureFlags', - ); - - expect( - controller.state.remoteFeatureFlags.multiVersionWrappedFlag, - ).toStrictEqual({ - enabled: true, - slippage: 0.5, - value: versionedFlagValue, - }); - }); - - it('preserves selected multi-version primitive value wrappers', async () => { - const mockApiService = buildClientConfigApiService(); - const mockFlags = { - multiVersionWrappedFlag: { - versions: { - '13.1.0': { - value: true, - }, - }, - }, - }; - - jest.spyOn(mockApiService, 'fetchRemoteFeatureFlags').mockResolvedValue({ - remoteFeatureFlags: mockFlags, - cacheTimestamp: Date.now(), - }); - - const { controller, messenger } = createController({ - clientConfigApiService: mockApiService, - clientVersion: '13.1.5', - }); - - await messenger.call( - 'RemoteFeatureFlagController:updateRemoteFeatureFlags', - ); - - expect( - controller.state.remoteFeatureFlags.multiVersionWrappedFlag, - ).toStrictEqual({ - value: true, - }); - }); }); describe('getDefaultRemoteFeatureFlagControllerState', () => { diff --git a/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts b/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts index 1b7a9c160a..c62209e41c 100644 --- a/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts +++ b/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts @@ -28,10 +28,6 @@ const THRESHOLD_VALUE_VERSION = 2; type JsonObject = Record; -type FeatureFlagValueWrapper = JsonObject & { - value: Json; -}; - // === STATE === export type RemoteFeatureFlagControllerState = { @@ -129,27 +125,6 @@ function isJsonObject(value: Json): value is JsonObject { return typeof value === 'object' && value !== null && !Array.isArray(value); } -function isFeatureFlagValueWrapper( - value: Json, -): value is FeatureFlagValueWrapper { - return ( - isJsonObject(value) && Object.prototype.hasOwnProperty.call(value, 'value') - ); -} - -function spreadFeatureFlagValueWrapper( - featureFlagValue: FeatureFlagValueWrapper, -): Json { - if (!isJsonObject(featureFlagValue.value)) { - return featureFlagValue; - } - - return { - ...featureFlagValue, - ...featureFlagValue.value, - }; -} - function normalizeThresholdValue(featureFlag: FeatureFlagScopeValue): Json { if (featureFlag.thresholdVersion === THRESHOLD_VALUE_VERSION) { return featureFlag.value; @@ -358,9 +333,7 @@ export class RemoteFeatureFlagController extends BaseController< return null; } - return isFeatureFlagValueWrapper(versionData) - ? spreadFeatureFlagValueWrapper(versionData) - : versionData; + return versionData; } async #processRemoteFeatureFlags(remoteFeatureFlags: FeatureFlags): Promise<{ From b0a1f1186c664ff564be6869218ab5e17c99fff8 Mon Sep 17 00:00:00 2001 From: Pedro Figueiredo Date: Thu, 28 May 2026 14:32:06 +0100 Subject: [PATCH 3/5] Use enum for threshold versions --- .../src/remote-feature-flag-controller.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts b/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts index c62209e41c..18229d872f 100644 --- a/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts +++ b/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts @@ -24,7 +24,10 @@ import { isVersionFeatureFlag, getVersionData } from './utils/version'; export const controllerName = 'RemoteFeatureFlagController'; export const DEFAULT_CACHE_DURATION = 24 * 60 * 60 * 1000; // 1 day -const THRESHOLD_VALUE_VERSION = 2; + +enum ThresholdVersion { + DirectValue = 2, +} type JsonObject = Record; @@ -126,7 +129,7 @@ function isJsonObject(value: Json): value is JsonObject { } function normalizeThresholdValue(featureFlag: FeatureFlagScopeValue): Json { - if (featureFlag.thresholdVersion === THRESHOLD_VALUE_VERSION) { + if (featureFlag.thresholdVersion === ThresholdVersion.DirectValue) { return featureFlag.value; } From 9dc313d31995de2d3f8eb75b4c1e1c2d2cfa4426 Mon Sep 17 00:00:00 2001 From: Pedro Figueiredo Date: Thu, 28 May 2026 14:37:21 +0100 Subject: [PATCH 4/5] Preserve legacy threshold wrapper fallback --- .../CHANGELOG.md | 2 +- .../remote-feature-flag-controller-types.ts | 2 +- .../remote-feature-flag-controller.test.ts | 39 +------------------ .../src/remote-feature-flag-controller.ts | 11 +----- 4 files changed, 4 insertions(+), 50 deletions(-) diff --git a/packages/remote-feature-flag-controller/CHANGELOG.md b/packages/remote-feature-flag-controller/CHANGELOG.md index e16c29af7d..0ef1c8e274 100644 --- a/packages/remote-feature-flag-controller/CHANGELOG.md +++ b/packages/remote-feature-flag-controller/CHANGELOG.md @@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -- Normalize object-valued threshold feature flag entries so `value` contents are exposed at the top level while preserving the `value` property, and support `thresholdVersion: 2` entries that return the selected `value` directly ([#8908](https://github.com/MetaMask/core/pull/8908)) +- Support `thresholdVersion: 2` threshold feature flag entries that return the selected `value` directly while preserving the existing threshold wrapper shape for unversioned entries ([#8908](https://github.com/MetaMask/core/pull/8908)) ## [4.2.1] diff --git a/packages/remote-feature-flag-controller/src/remote-feature-flag-controller-types.ts b/packages/remote-feature-flag-controller/src/remote-feature-flag-controller-types.ts index dd120e1871..81b953ba8f 100644 --- a/packages/remote-feature-flag-controller/src/remote-feature-flag-controller-types.ts +++ b/packages/remote-feature-flag-controller/src/remote-feature-flag-controller-types.ts @@ -40,7 +40,7 @@ export type FeatureFlagScope = { }; export type FeatureFlagScopeValue = { - name?: string; + name: string; thresholdName?: string; thresholdVersion?: number; scope: FeatureFlagScope; diff --git a/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.test.ts b/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.test.ts index 385fbf6b7b..f5f1b3fc23 100644 --- a/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.test.ts +++ b/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.test.ts @@ -473,7 +473,7 @@ describe('RemoteFeatureFlagController', () => { }); }); - it('spreads selected threshold object values while preserving the value property', async () => { + it('preserves selected legacy threshold object value wrappers', async () => { const thresholdFlagValue = { enabled: true, minimumVersion: '13.10.0', @@ -504,9 +504,6 @@ describe('RemoteFeatureFlagController', () => { controller.state.remoteFeatureFlags.thresholdObjectFlag, ).toStrictEqual({ name: 'enabled', - enabled: true, - minimumVersion: '13.10.0', - attemptsMax: 5, value: thresholdFlagValue, }); }); @@ -544,38 +541,6 @@ describe('RemoteFeatureFlagController', () => { ).toStrictEqual(thresholdFlagValue); }); - it('omits selected threshold name when no name metadata is configured', async () => { - const thresholdFlagValue = { - enabled: true, - }; - const mockFlags = { - thresholdObjectFlag: [ - { - scope: { type: 'threshold', value: 1.0 }, - value: thresholdFlagValue, - }, - ], - }; - const clientConfigApiService = buildClientConfigApiService({ - remoteFeatureFlags: mockFlags, - }); - const { controller, messenger } = createController({ - clientConfigApiService, - getMetaMetricsId: () => MOCK_METRICS_ID, - }); - - await messenger.call( - 'RemoteFeatureFlagController:updateRemoteFeatureFlags', - ); - - expect( - controller.state.remoteFeatureFlags.thresholdObjectFlag, - ).toStrictEqual({ - enabled: true, - value: thresholdFlagValue, - }); - }); - it('preserves non-threshold feature flags unchanged', async () => { const clientConfigApiService = buildClientConfigApiService({ remoteFeatureFlags: MOCK_FLAGS_WITH_THRESHOLD, @@ -1062,8 +1027,6 @@ describe('RemoteFeatureFlagController', () => { // Threshold = 0.094878, which falls in groupA range (t <= 0.3) expect(multiVersionABFlag).toStrictEqual({ name: 'groupA', - feature: 'A', - enabled: true, value: { feature: 'A', enabled: true }, }); expect(regularFlag).toBe(true); diff --git a/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts b/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts index 18229d872f..20fdc88605 100644 --- a/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts +++ b/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts @@ -29,8 +29,6 @@ enum ThresholdVersion { DirectValue = 2, } -type JsonObject = Record; - // === STATE === export type RemoteFeatureFlagControllerState = { @@ -124,20 +122,13 @@ export function getDefaultRemoteFeatureFlagControllerState(): RemoteFeatureFlagC }; } -function isJsonObject(value: Json): value is JsonObject { - return typeof value === 'object' && value !== null && !Array.isArray(value); -} - function normalizeThresholdValue(featureFlag: FeatureFlagScopeValue): Json { if (featureFlag.thresholdVersion === ThresholdVersion.DirectValue) { return featureFlag.value; } - const name = featureFlag.thresholdName ?? featureFlag.name; - return { - ...(isJsonObject(featureFlag.value) ? featureFlag.value : {}), - ...(name === undefined ? {} : { name }), + name: featureFlag.name, value: featureFlag.value, }; } From 363c9fd133fcf56929a11abefa648ad23163a2de Mon Sep 17 00:00:00 2001 From: Pedro Figueiredo Date: Thu, 28 May 2026 16:17:00 +0100 Subject: [PATCH 5/5] Restore direct version data return --- .../src/remote-feature-flag-controller.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts b/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts index 20fdc88605..94d97c45e2 100644 --- a/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts +++ b/packages/remote-feature-flag-controller/src/remote-feature-flag-controller.ts @@ -321,13 +321,7 @@ export class RemoteFeatureFlagController extends BaseController< return flagValue; } - const versionData = getVersionData(flagValue, this.#clientVersion); - - if (versionData === null) { - return null; - } - - return versionData; + return getVersionData(flagValue, this.#clientVersion); } async #processRemoteFeatureFlags(remoteFeatureFlags: FeatureFlags): Promise<{