From d80de280ab09aa3dced454af5e5401b400ffd258 Mon Sep 17 00:00:00 2001 From: Elliot Winkler Date: Mon, 3 Nov 2025 07:50:59 -0700 Subject: [PATCH 1/6] Ensure networksMetadata never references old network client IDs In debugging a long-standing issue where SelectedNetworkController sometimes requests invalid network client IDs from NetworkController, one bug was discovered in NetworkController. Namely, when a network is removed, its data is removed from `networkConfigurationsByChainId`, but not `networksMetadata`. This commit fixes `removeNetwork` to do this, and ensures that when the controller is initialized, if `networksMetadata` contains invalid network client IDs, they are removed. --- packages/network-controller/CHANGELOG.md | 6 + .../src/NetworkController.ts | 25 +- .../tests/NetworkController.test.ts | 267 +++++++++++++----- 3 files changed, 218 insertions(+), 80 deletions(-) diff --git a/packages/network-controller/CHANGELOG.md b/packages/network-controller/CHANGELOG.md index 2a91681de86..879bc61d255 100644 --- a/packages/network-controller/CHANGELOG.md +++ b/packages/network-controller/CHANGELOG.md @@ -13,6 +13,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Providers accessible either via network clients or global proxies no longer emit events (or inherit from EventEmitter, for that matter). - Bump `@metamask/controller-utils` from `^11.14.1` to `^11.15.0` ([#7003](https://github.com/MetaMask/core/pull/7003)) +### Fixed + +- Ensure `networksMetadata` never references old network client IDs ([#7047](https://github.com/MetaMask/core/pull/7047)) + - When removing a network configuration, ensure that metadata for all RPC endpoints in the network configuration are also removed from `networksMetadata` + - When initializing the controller, remove metadata for RPC endpoints in `networksMetadata` that are not present in a network configuration + ## [25.0.0] ### Changed diff --git a/packages/network-controller/src/NetworkController.ts b/packages/network-controller/src/NetworkController.ts index 2449fe7c53d..206e8250e24 100644 --- a/packages/network-controller/src/NetworkController.ts +++ b/packages/network-controller/src/NetworkController.ts @@ -1082,12 +1082,12 @@ function correctInitialState( const networkConfigurationsSortedByChainId = getNetworkConfigurations( state, ).sort((a, b) => a.chainId.localeCompare(b.chainId)); - const networkClientIds = getAvailableNetworkClientIds( + const availableNetworkClientIds = getAvailableNetworkClientIds( networkConfigurationsSortedByChainId, ); return produce(state, (newState) => { - if (!networkClientIds.includes(state.selectedNetworkClientId)) { + if (!availableNetworkClientIds.includes(state.selectedNetworkClientId)) { const firstNetworkConfiguration = networkConfigurationsSortedByChainId[0]; const newSelectedNetworkClientId = firstNetworkConfiguration.rpcEndpoints[ @@ -1101,6 +1101,23 @@ function correctInitialState( ); newState.selectedNetworkClientId = newSelectedNetworkClientId; } + + const invalidNetworkClientIdsWithMetadata = Object.keys( + state.networksMetadata, + ).filter( + (networkClientId) => !availableNetworkClientIds.includes(networkClientId), + ); + if (invalidNetworkClientIdsWithMetadata.length > 0) { + for (const invalidNetworkClientId of invalidNetworkClientIdsWithMetadata) { + delete state.networksMetadata[invalidNetworkClientId]; + } + messenger.call( + 'ErrorReportingService:captureException', + new Error( + '`networksMetadata` had invalid network client IDs which have been removed', + ), + ); + } }); } @@ -2401,6 +2418,10 @@ export class NetworkController extends BaseController< mode: 'remove', existingNetworkConfiguration, }); + + for (const rpcEndpoint of existingNetworkConfiguration.rpcEndpoints) { + delete state.networksMetadata[rpcEndpoint.networkClientId]; + } }); this.messenger.publish( diff --git a/packages/network-controller/tests/NetworkController.test.ts b/packages/network-controller/tests/NetworkController.test.ts index ab7ea3aa877..ea34e9836bb 100644 --- a/packages/network-controller/tests/NetworkController.test.ts +++ b/packages/network-controller/tests/NetworkController.test.ts @@ -350,90 +350,111 @@ describe('NetworkController', () => { ); }); - describe('if selectedNetworkClientId does not match the networkClientId of an RPC endpoint in networkConfigurationsByChainId', () => { - it('corrects selectedNetworkClientId to the default RPC endpoint of the first chain', () => { - const messenger = buildRootMessenger(); - messenger.registerActionHandler( - 'ErrorReportingService:captureException', - jest.fn(), - ); - const controllerMessenger = buildNetworkControllerMessenger(messenger); - const controller = new NetworkController({ - messenger: controllerMessenger, - state: { - selectedNetworkClientId: 'nonexistent', - networkConfigurationsByChainId: { - '0x1': buildCustomNetworkConfiguration({ - chainId: '0x1', - defaultRpcEndpointIndex: 1, - rpcEndpoints: [ - buildCustomRpcEndpoint({ - networkClientId: 'AAAA-AAAA-AAAA-AAAA', - }), - buildCustomRpcEndpoint({ - networkClientId: 'BBBB-BBBB-BBBB-BBBB', - }), - ], - }), - '0x2': buildCustomNetworkConfiguration({ chainId: '0x2' }), - '0x3': buildCustomNetworkConfiguration({ chainId: '0x3' }), - }, - }, - infuraProjectId: 'infura-project-id', - getRpcServiceOptions: () => ({ - fetch, - btoa, - }), - }); + it('corrects an invalid selectedNetworkClientId to the default RPC endpoint of the first chain, logging this fact', () => { + const messenger = buildRootMessenger(); + const captureExceptionMock = jest.fn(); + messenger.registerActionHandler( + 'ErrorReportingService:captureException', + captureExceptionMock, + ); + const controllerMessenger = buildNetworkControllerMessenger(messenger); - expect(controller.state.selectedNetworkClientId).toBe( - 'BBBB-BBBB-BBBB-BBBB', - ); + const controller = new NetworkController({ + messenger: controllerMessenger, + state: { + selectedNetworkClientId: 'nonexistent', + networkConfigurationsByChainId: { + '0x1': buildCustomNetworkConfiguration({ + chainId: '0x1', + defaultRpcEndpointIndex: 1, + rpcEndpoints: [ + buildCustomRpcEndpoint({ + networkClientId: 'AAAA-AAAA-AAAA-AAAA', + }), + buildCustomRpcEndpoint({ + networkClientId: 'BBBB-BBBB-BBBB-BBBB', + }), + ], + }), + '0x2': buildCustomNetworkConfiguration({ chainId: '0x2' }), + '0x3': buildCustomNetworkConfiguration({ chainId: '0x3' }), + }, + }, + infuraProjectId: 'infura-project-id', + getRpcServiceOptions: () => ({ + fetch, + btoa, + }), }); - it('logs a Sentry error', () => { - const messenger = buildRootMessenger(); - const captureExceptionMock = jest.fn(); - messenger.registerActionHandler( - 'ErrorReportingService:captureException', - captureExceptionMock, - ); - const controllerMessenger = buildNetworkControllerMessenger(messenger); + expect(controller.state.selectedNetworkClientId).toBe( + 'BBBB-BBBB-BBBB-BBBB', + ); + expect(captureExceptionMock).toHaveBeenCalledWith( + new Error( + "`selectedNetworkClientId` 'nonexistent' does not refer to an RPC endpoint within a network configuration; correcting to 'BBBB-BBBB-BBBB-BBBB'", + ), + ); + }); - new NetworkController({ - messenger: controllerMessenger, - state: { - selectedNetworkClientId: 'nonexistent', - networkConfigurationsByChainId: { - '0x1': buildCustomNetworkConfiguration({ - chainId: '0x1', - defaultRpcEndpointIndex: 1, - rpcEndpoints: [ - buildCustomRpcEndpoint({ - networkClientId: 'AAAA-AAAA-AAAA-AAAA', - }), - buildCustomRpcEndpoint({ - networkClientId: 'BBBB-BBBB-BBBB-BBBB', - }), - ], - }), - '0x2': buildCustomNetworkConfiguration({ chainId: '0x2' }), - '0x3': buildCustomNetworkConfiguration({ chainId: '0x3' }), + it('removes invalid network client IDs from networksMetadata, logging this fact', () => { + const messenger = buildRootMessenger(); + const captureExceptionMock = jest.fn(); + messenger.registerActionHandler( + 'ErrorReportingService:captureException', + captureExceptionMock, + ); + const controllerMessenger = buildNetworkControllerMessenger(messenger); + + const controller = new NetworkController({ + messenger: controllerMessenger, + state: { + selectedNetworkClientId: InfuraNetworkType.sepolia, + networkConfigurationsByChainId: { + [ChainId.sepolia]: buildInfuraNetworkConfiguration( + InfuraNetworkType.sepolia, + ), + }, + networksMetadata: { + [InfuraNetworkType.sepolia]: { + status: NetworkStatus.Available, + EIPS: {}, + }, + 'AAAA-AAAA-AAAA-AAAA': { + status: NetworkStatus.Available, + EIPS: {}, + }, + 'BBBB-BBBB-BBBB-BBBB': { + status: NetworkStatus.Available, + EIPS: {}, + }, + 'CCCC-CCCC-CCCC-CCCC': { + status: NetworkStatus.Available, + EIPS: {}, }, }, - infuraProjectId: 'infura-project-id', - getRpcServiceOptions: () => ({ - fetch, - btoa, - }), - }); - - expect(captureExceptionMock).toHaveBeenCalledWith( - new Error( - "`selectedNetworkClientId` 'nonexistent' does not refer to an RPC endpoint within a network configuration; correcting to 'BBBB-BBBB-BBBB-BBBB'", - ), - ); + }, + infuraProjectId: 'infura-project-id', + getRpcServiceOptions: () => ({ + fetch, + btoa, + }), }); + + expect(controller.state.networksMetadata).not.toHaveProperty( + 'AAAA-AAAA-AAAA-AAAA', + ); + expect(controller.state.networksMetadata).not.toHaveProperty( + 'BBBB-BBBB-BBBB-BBBB', + ); + expect(controller.state.networksMetadata).not.toHaveProperty( + 'CCCC-CCCC-CCCC-CCCC', + ); + expect(captureExceptionMock).toHaveBeenCalledWith( + new Error( + '`networksMetadata` had invalid network client IDs which have been removed', + ), + ); }); const invalidInfuraProjectIds = [undefined, null, {}, 1]; @@ -13130,6 +13151,41 @@ describe('NetworkController', () => { ); }); + it('removes the existing metadata for the network from state', async () => { + await withController( + { + state: { + selectedNetworkClientId: 'AAAA-AAAA-AAAA-AAAA', + networkConfigurationsByChainId: { + [infuraChainId]: + buildInfuraNetworkConfiguration(infuraNetworkType), + '0x1337': buildCustomNetworkConfiguration({ + chainId: '0x1337', + rpcEndpoints: [ + buildCustomRpcEndpoint({ + networkClientId: 'AAAA-AAAA-AAAA-AAAA', + }), + ], + }), + }, + networksMetadata: { + [infuraNetworkType]: { + status: NetworkStatus.Available, + EIPS: {}, + }, + }, + }, + }, + ({ controller }) => { + controller.removeNetwork(infuraChainId); + + expect(controller.state.networksMetadata).not.toHaveProperty( + infuraNetworkType, + ); + }, + ); + }); + it('destroys and unregisters the network clients for each of the RPC endpoints defined in the network configuration (even the Infura endpoint)', async () => { const defaultRpcEndpoint = buildInfuraRpcEndpoint(infuraNetworkType); @@ -13190,7 +13246,7 @@ describe('NetworkController', () => { } describe('given the ID of a non-Infura-supported chain', () => { - it('removes the existing network configuration', async () => { + it('removes the existing network configuration from state', async () => { await withController( { state: { @@ -13217,6 +13273,61 @@ describe('NetworkController', () => { ); }); + it('removes the existing metadata for all RPC endpoints in the network from state', async () => { + await withController( + { + state: { + selectedNetworkClientId: TESTNET.networkType, + networkConfigurationsByChainId: { + '0x1337': buildCustomNetworkConfiguration({ + rpcEndpoints: [ + buildCustomRpcEndpoint({ + networkClientId: 'AAAA-AAAA-AAAA-AAAA', + }), + buildCustomRpcEndpoint({ + networkClientId: 'BBBB-BBBB-BBBB-BBBB', + }), + buildCustomRpcEndpoint({ + networkClientId: 'CCCC-CCCC-CCCC-CCCC', + }), + ], + }), + [TESTNET.chainId]: buildInfuraNetworkConfiguration( + TESTNET.networkType, + ), + }, + networksMetadata: { + 'AAAA-AAAA-AAAA-AAAA': { + status: NetworkStatus.Available, + EIPS: {}, + }, + 'BBBB-BBBB-BBBB-BBBB': { + status: NetworkStatus.Available, + EIPS: {}, + }, + 'CCCC-CCCC-CCCC-CCCC': { + status: NetworkStatus.Available, + EIPS: {}, + }, + }, + }, + }, + ({ controller }) => { + controller.removeNetwork('0x1337'); + + expect(controller.state.networksMetadata).not.toHaveProperty( + 'AAAA-AAAA-AAAA-AAAA', + ); + expect(controller.state.networksMetadata).not.toHaveProperty( + 'BBBB-BBBB-BBBB-BBBB', + ); + expect(controller.state.networksMetadata).not.toHaveProperty( + 'CCCC-CCCC-CCCC-CCCC', + ); + }, + ); + }); + it('destroys the network clients for each of the RPC endpoints defined in the network configuration', async () => { await withController( { From 759fd13503a7816245d9d7d68e4e479425f59f6f Mon Sep 17 00:00:00 2001 From: Elliot Winkler Date: Mon, 3 Nov 2025 12:38:46 -0700 Subject: [PATCH 2/6] Fix GasFeeController tests --- .../src/GasFeeController.test.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/packages/gas-fee-controller/src/GasFeeController.test.ts b/packages/gas-fee-controller/src/GasFeeController.test.ts index 9f9e8d74c89..d0635c7cd02 100644 --- a/packages/gas-fee-controller/src/GasFeeController.test.ts +++ b/packages/gas-fee-controller/src/GasFeeController.test.ts @@ -4,6 +4,8 @@ import { convertHexToDecimal, toHex, } from '@metamask/controller-utils'; +import type { ErrorReportingServiceMessenger } from '@metamask/error-reporting-service'; +import { ErrorReportingService } from '@metamask/error-reporting-service'; import EthQuery from '@metamask/eth-query'; import { Messenger, @@ -77,6 +79,21 @@ const setupNetworkController = async ({ clock: sinon.SinonFakeTimers; initializeProvider?: boolean; }) => { + const errorReportingMessenger = new Messenger< + 'ErrorReportingService', + MessengerActions, + MessengerEvents, + typeof rootMessenger + >({ + namespace: 'ErrorReportingService', + parent: rootMessenger, + }); + + new ErrorReportingService({ + messenger: errorReportingMessenger, + captureException: jest.fn(), + }); + const networkControllerMessenger = new Messenger< 'NetworkController', MessengerActions, From 20b60314e1beb230637a992b1566e362d1313927 Mon Sep 17 00:00:00 2001 From: Elliot Winkler Date: Mon, 3 Nov 2025 12:53:41 -0700 Subject: [PATCH 3/6] Really fix GasFeeController tests --- packages/gas-fee-controller/src/GasFeeController.test.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/gas-fee-controller/src/GasFeeController.test.ts b/packages/gas-fee-controller/src/GasFeeController.test.ts index d0635c7cd02..2a63f6d2189 100644 --- a/packages/gas-fee-controller/src/GasFeeController.test.ts +++ b/packages/gas-fee-controller/src/GasFeeController.test.ts @@ -103,6 +103,10 @@ const setupNetworkController = async ({ namespace: 'NetworkController', parent: rootMessenger, }); + rootMessenger.delegate({ + messenger: networkControllerMessenger, + actions: ['ErrorReportingService:captureException'], + }); const infuraProjectId = '123'; From 6bc00e5e75810f81431d4b7149d9b8d5ef56bbf6 Mon Sep 17 00:00:00 2001 From: Elliot Winkler Date: Mon, 3 Nov 2025 13:27:44 -0700 Subject: [PATCH 4/6] Fix more tests --- .../src/GasFeeController.test.ts | 26 +++++++--------- .../src/NetworkController.ts | 2 +- .../tests/NetworkController.test.ts | 30 +++++++++---------- packages/network-controller/tests/helpers.ts | 24 +++++++++++++-- 4 files changed, 48 insertions(+), 34 deletions(-) diff --git a/packages/gas-fee-controller/src/GasFeeController.test.ts b/packages/gas-fee-controller/src/GasFeeController.test.ts index 2a63f6d2189..94ce2e95721 100644 --- a/packages/gas-fee-controller/src/GasFeeController.test.ts +++ b/packages/gas-fee-controller/src/GasFeeController.test.ts @@ -65,7 +65,16 @@ type AllEvents = AllGasFeeControllerEvents | AllNetworkControllerEvents; type RootMessenger = Messenger; const getRootMessenger = (): RootMessenger => { - return new Messenger({ namespace: MOCK_ANY_NAMESPACE }); + const rootMessenger = new Messenger< + MockAnyNamespace, + MessengerActions, + MessengerEvents + >({ namespace: MOCK_ANY_NAMESPACE }); + rootMessenger.registerActionHandler( + 'ErrorReportingService:captureException', + jest.fn(), + ); + return rootMessenger; }; const setupNetworkController = async ({ @@ -79,21 +88,6 @@ const setupNetworkController = async ({ clock: sinon.SinonFakeTimers; initializeProvider?: boolean; }) => { - const errorReportingMessenger = new Messenger< - 'ErrorReportingService', - MessengerActions, - MessengerEvents, - typeof rootMessenger - >({ - namespace: 'ErrorReportingService', - parent: rootMessenger, - }); - - new ErrorReportingService({ - messenger: errorReportingMessenger, - captureException: jest.fn(), - }); - const networkControllerMessenger = new Messenger< 'NetworkController', MessengerActions, diff --git a/packages/network-controller/src/NetworkController.ts b/packages/network-controller/src/NetworkController.ts index 206e8250e24..a95a97fd037 100644 --- a/packages/network-controller/src/NetworkController.ts +++ b/packages/network-controller/src/NetworkController.ts @@ -1114,7 +1114,7 @@ function correctInitialState( messenger.call( 'ErrorReportingService:captureException', new Error( - '`networksMetadata` had invalid network client IDs which have been removed', + '`networksMetadata` had invalid network client IDs, which have been removed', ), ); } diff --git a/packages/network-controller/tests/NetworkController.test.ts b/packages/network-controller/tests/NetworkController.test.ts index ea34e9836bb..77be127ecbd 100644 --- a/packages/network-controller/tests/NetworkController.test.ts +++ b/packages/network-controller/tests/NetworkController.test.ts @@ -351,12 +351,12 @@ describe('NetworkController', () => { }); it('corrects an invalid selectedNetworkClientId to the default RPC endpoint of the first chain, logging this fact', () => { - const messenger = buildRootMessenger(); const captureExceptionMock = jest.fn(); - messenger.registerActionHandler( - 'ErrorReportingService:captureException', - captureExceptionMock, - ); + const messenger = buildRootMessenger({ + actionHandlers: { + 'ErrorReportingService:captureException': captureExceptionMock, + }, + }); const controllerMessenger = buildNetworkControllerMessenger(messenger); const controller = new NetworkController({ @@ -398,12 +398,12 @@ describe('NetworkController', () => { }); it('removes invalid network client IDs from networksMetadata, logging this fact', () => { - const messenger = buildRootMessenger(); const captureExceptionMock = jest.fn(); - messenger.registerActionHandler( - 'ErrorReportingService:captureException', - captureExceptionMock, - ); + const messenger = buildRootMessenger({ + actionHandlers: { + 'ErrorReportingService:captureException': captureExceptionMock, + }, + }); const controllerMessenger = buildNetworkControllerMessenger(messenger); const controller = new NetworkController({ @@ -452,7 +452,7 @@ describe('NetworkController', () => { ); expect(captureExceptionMock).toHaveBeenCalledWith( new Error( - '`networksMetadata` had invalid network client IDs which have been removed', + '`networksMetadata` had invalid network client IDs, which have been removed', ), ); }); @@ -852,7 +852,7 @@ describe('NetworkController', () => { }, }, networksMetadata: { - mainnet: { + [TESTNET.networkType]: { EIPS: { 1559: true }, status: NetworkStatus.Unknown, }, @@ -886,7 +886,7 @@ describe('NetworkController', () => { }, }, "networksMetadata": Object { - "mainnet": Object { + "sepolia": Object { "EIPS": Object { "1559": true, }, @@ -15682,7 +15682,7 @@ function lookupNetworkTests({ state: { ...initialState, networksMetadata: { - mainnet: { + [expectedNetworkClientId]: { EIPS: { 1559: false }, status: NetworkStatus.Unknown, }, @@ -15725,7 +15725,7 @@ function lookupNetworkTests({ state: { ...initialState, networksMetadata: { - mainnet: { + [expectedNetworkClientId]: { EIPS: { 1559: true }, status: NetworkStatus.Unknown, }, diff --git a/packages/network-controller/tests/helpers.ts b/packages/network-controller/tests/helpers.ts index bff0d7f5010..5864da9deba 100644 --- a/packages/network-controller/tests/helpers.ts +++ b/packages/network-controller/tests/helpers.ts @@ -43,6 +43,7 @@ import type { InfuraNetworkClientConfiguration, } from '../src/types'; import { NetworkClientType } from '../src/types'; +import { ErrorReportingServiceCaptureExceptionAction } from '@metamask/error-reporting-service'; export type AllNetworkControllerActions = MessengerActions; @@ -82,10 +83,29 @@ export const TESTNET = { * Build a root messenger that includes all events used by the network * controller. * + * @param options - Options. + * @param options.actionHandlers - Handlers for actions that are pre-registered + * on the messenger. * @returns The messenger. */ -export function buildRootMessenger(): RootMessenger { - return new Messenger({ namespace: MOCK_ANY_NAMESPACE }); +export function buildRootMessenger({ + actionHandlers = {}, +}: { + actionHandlers?: { + 'ErrorReportingService:captureException'?: ErrorReportingServiceCaptureExceptionAction['handler']; + }; +} = {}): RootMessenger { + const rootMessenger = new Messenger< + MockAnyNamespace, + MessengerActions, + MessengerEvents + >({ namespace: MOCK_ANY_NAMESPACE }); + rootMessenger.registerActionHandler( + 'ErrorReportingService:captureException', + actionHandlers['ErrorReportingService:captureException'] ?? + ((error) => console.error(error)), + ); + return rootMessenger; } /** From 133e5c68008605d77cef28adc90a811ce5fe3a6a Mon Sep 17 00:00:00 2001 From: Elliot Winkler Date: Mon, 3 Nov 2025 13:32:46 -0700 Subject: [PATCH 5/6] Fix lint violations --- packages/gas-fee-controller/src/GasFeeController.test.ts | 2 -- packages/network-controller/tests/helpers.ts | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/gas-fee-controller/src/GasFeeController.test.ts b/packages/gas-fee-controller/src/GasFeeController.test.ts index 94ce2e95721..562589f8064 100644 --- a/packages/gas-fee-controller/src/GasFeeController.test.ts +++ b/packages/gas-fee-controller/src/GasFeeController.test.ts @@ -4,8 +4,6 @@ import { convertHexToDecimal, toHex, } from '@metamask/controller-utils'; -import type { ErrorReportingServiceMessenger } from '@metamask/error-reporting-service'; -import { ErrorReportingService } from '@metamask/error-reporting-service'; import EthQuery from '@metamask/eth-query'; import { Messenger, diff --git a/packages/network-controller/tests/helpers.ts b/packages/network-controller/tests/helpers.ts index 5864da9deba..a709fb799c6 100644 --- a/packages/network-controller/tests/helpers.ts +++ b/packages/network-controller/tests/helpers.ts @@ -5,6 +5,7 @@ import { NetworksTicker, toHex, } from '@metamask/controller-utils'; +import type { ErrorReportingServiceCaptureExceptionAction } from '@metamask/error-reporting-service'; import { Messenger, type MockAnyNamespace, @@ -43,7 +44,6 @@ import type { InfuraNetworkClientConfiguration, } from '../src/types'; import { NetworkClientType } from '../src/types'; -import { ErrorReportingServiceCaptureExceptionAction } from '@metamask/error-reporting-service'; export type AllNetworkControllerActions = MessengerActions; From 1618688514e4849a3eb6911fafe41c7d1ed24be6 Mon Sep 17 00:00:00 2001 From: Elliot Winkler Date: Tue, 4 Nov 2025 07:36:08 -0700 Subject: [PATCH 6/6] Use newState instead of state --- packages/network-controller/src/NetworkController.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/network-controller/src/NetworkController.ts b/packages/network-controller/src/NetworkController.ts index a95a97fd037..e8204301abc 100644 --- a/packages/network-controller/src/NetworkController.ts +++ b/packages/network-controller/src/NetworkController.ts @@ -1085,6 +1085,11 @@ function correctInitialState( const availableNetworkClientIds = getAvailableNetworkClientIds( networkConfigurationsSortedByChainId, ); + const invalidNetworkClientIdsWithMetadata = Object.keys( + state.networksMetadata, + ).filter( + (networkClientId) => !availableNetworkClientIds.includes(networkClientId), + ); return produce(state, (newState) => { if (!availableNetworkClientIds.includes(state.selectedNetworkClientId)) { @@ -1102,14 +1107,9 @@ function correctInitialState( newState.selectedNetworkClientId = newSelectedNetworkClientId; } - const invalidNetworkClientIdsWithMetadata = Object.keys( - state.networksMetadata, - ).filter( - (networkClientId) => !availableNetworkClientIds.includes(networkClientId), - ); if (invalidNetworkClientIdsWithMetadata.length > 0) { for (const invalidNetworkClientId of invalidNetworkClientIdsWithMetadata) { - delete state.networksMetadata[invalidNetworkClientId]; + delete newState.networksMetadata[invalidNetworkClientId]; } messenger.call( 'ErrorReportingService:captureException',