Skip to content

Correct invalid initial selectedNetworkClientId#15941

Merged
NicolasMassart merged 3 commits intorelease/7.47.0from
fix-incident-1051
Jun 5, 2025
Merged

Correct invalid initial selectedNetworkClientId#15941
NicolasMassart merged 3 commits intorelease/7.47.0from
fix-incident-1051

Conversation

@mcmire
Copy link
Copy Markdown
Contributor

@mcmire mcmire commented May 30, 2025

Description

Currently, when NetworkController is instantiated with pre-existing state that contains an invalid selectedNetworkClientId — that is, no RPC endpoint exists which has the same network client ID — then it throws an error. This was intentionally done to bring attention to possible bugs in NetworkController, but this has the unfortunate side effect of bricking users' wallets.

To fix this, we now correct an invalid selectedNetworkClientId to point to the default RPC endpoint of the first network sorted by chain ID (which in the vast majority of cases will be Mainnet). We still do want to know about this, though, so we log the error in Sentry.

Related issues

See MetaMask/core#5851 for the equivalent changes to network-controller that were copied here.

Manual testing steps

  1. Check out this branch.
  2. Run yarn setup:expo.
  3. We now have to force the initial state to be invalid. Open Engine.ts, scroll down to where NetworkController is initialized, and apply these changes:
          const networkControllerOpts = {
            infuraProjectId: process.env.MM_INFURA_PROJECT_ID || NON_EMPTY,
    -       state: initialState.NetworkController,
    +       state: {
    +         ...initialState.NetworkController,
    +         selectedNetworkClientId: "nonexistent",
    +       },
            messenger: this.controllerMessenger.getRestricted({
              name: 'NetworkController',
              allowedEvents: [],
              allowedActions: [],
            }) as unknown as NetworkControllerMessenger,
            getRpcServiceOptions: () => ({
              fetch,
              btoa,
            }),
            additionalDefaultNetworks: [ChainId['megaeth-testnet']],
            captureException,
          };
          const networkController = new NetworkController(networkControllerOpts);
    +     Logger.log('selectedNetworkClientId', networkController.state.selectedNetworkClientId);
  4. Run yarn watch:clean.
  5. Load the app, onboarding if necessary.
  6. You should be able to get to the home screen without issues. If you check the terminal you should see a line that says selectedNetworkClientId mainnet. This proves that although the initial selectedNetworkClientId was invalid, it was auto-corrected to "mainnet".

Screenshots/Recordings

(N/A)

Before

After

Pre-merge author checklist

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Currently, when NetworkController is instantiated with pre-existing
state that contains an invalid `selectedNetworkClientId` — that is, no
RPC endpoint exists which has the same network client ID — then it
throws an error. This was intentionally done to bring attention to
possible bugs in NetworkController, but this has the unfortunate side
effect of bricking users' wallets.

To fix this, we now correct an invalid `selectedNetworkClientId` to
point to the default RPC endpoint of the first network sorted by chain
ID (which in the vast majority of cases will be Mainnet). We still do
want to know about this, though, so we log the error in Sentry.
@github-actions
Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbot metamaskbot added the team-wallet-framework-deprecated DEPRECATED: please use "team-core-platform" instead label May 30, 2025
@github-actions

This comment was marked as outdated.

@github-actions

This comment was marked as outdated.

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Jun 4, 2025

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jun 4, 2025

https://bitrise.io/ Bitrise

❌❌❌ pr_smoke_e2e_pipeline failed on Bitrise! ❌❌❌

Commit hash: 0db14fe
Build link: https://app.bitrise.io/app/be69d4368ee7e86d/pipelines/9d156042-1dd4-4c59-87e9-6c2233c2697c

Note

  • You can kick off another pr_smoke_e2e_pipeline on Bitrise by removing and re-applying the Run Smoke E2E label on the pull request

Tip

  • Check the documentation if you have any doubts on how to understand the failure on bitrise

@NicolasMassart NicolasMassart added the release-blocker This bug is blocking the next release label Jun 4, 2025
@mcmire mcmire marked this pull request as ready for review June 4, 2025 21:19
@mcmire mcmire requested a review from a team June 4, 2025 21:19
@mcmire
Copy link
Copy Markdown
Contributor Author

mcmire commented Jun 4, 2025

I'm not sure why Bitrise is failing. I selected a few e2e tests to run locally, and they all passed. Additionally, the release/7.47.0 already does not pass CI.

DDDDDanica pushed a commit to MetaMask/metamask-extension that referenced this pull request Jun 4, 2025
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

If `selectedNetworkClientId` in NetworkController state does not point
to an RPC endpoint and therefore does not also point to a network
client, then we automatically correct it to point to the default RPC
endpoint of the first network (sorted by chain ID). This allows the
wallet to start normally.

This change is being added as a patch because we do not want to upgrade
to 23.5.1, as doing so would fix another unrelated bug, and we want to
limit the scope of the change.

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/33480?quickstart=1)

## **Related issues**

See MetaMask/core#5851 for the equivalent
changes to network-controller that were copied here.

Also see MetaMask/metamask-mobile#15941 for a
similar fix on the mobile side.

## **Manual testing steps**

1. Check out this branch.
2. Run `yarn start`.
3. Open the extension, and go through onboarding.
4. Close the UI.
5. Find the extension and open the service worker.
6. Navigate to the Application tab.
7. Click on "Extension storage", then "Local".
8. Click on the value for "data".
9. Look in the preview pane below (rendered JSON), right-click and
choose "Copy value".
10. Paste the value in another screen such as TextEdit.
11. Look for `selectedNetworkClientId` and change it to something
invalid.
12. Reload the extension.
13. The extension should still load successfully.
14. Go back to the service worker. You should still be on the
Application tab, and the preview should have been updated so that
`selectedNetworkClientId` should no longer be invalid.
15. Repeat the same steps, except run `yarn webpack --watch` instead of
`yarn start` (to test MV2).

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

(N/A)

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

---------

Co-authored-by: MetaMask Bot <metamaskbot@users.noreply.github.com>
@NicolasMassart NicolasMassart requested a review from Copilot June 5, 2025 09:10
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR backports a fix to automatically correct invalid selectedNetworkClientId values in the NetworkController, logging errors to Sentry instead of throwing and bricking the app. It also updates the Engine initialization to pass the Sentry captureException handler into the controller.

  • Rename validateNetworkControllerState to validateInitialState and remove strict throw on invalid selection.
  • Introduce correctInitialState using Immer to adjust invalid selectedNetworkClientId, logging via captureException.
  • Update Engine to import and supply captureException when creating NetworkController.

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
patches/@MetaMask+network-controller+23.2.1-backport.patch Adds validateInitialState, correctInitialState, updates constructor to apply corrections and log errors.
app/core/Engine/Engine.ts Imports captureException and supplies it to networkControllerOpts.
Comments suppressed due to low confidence (2)

node_modules/@metamask/network-controller/dist/NetworkController.cjs:42

  • Add unit tests for correctInitialState to ensure invalid selectedNetworkClientId values are corrected properly and errors are logged as intended.
function correctInitialState(state, captureException) {

node_modules/@metamask/network-controller/dist/NetworkController.cjs:61

  • Consider providing a default no-op for captureException or validating that options.captureException is a function before use to prevent runtime errors if it's undefined.
const { messenger, state, infuraProjectId, log, getRpcServiceOptions, additionalDefaultNetworks, captureException, } = options;

@NicolasMassart NicolasMassart merged commit 00a364e into release/7.47.0 Jun 5, 2025
41 of 44 checks passed
@NicolasMassart NicolasMassart deleted the fix-incident-1051 branch June 5, 2025 09:15
@github-actions github-actions bot locked and limited conversation to collaborators Jun 5, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-blocker This bug is blocking the next release team-wallet-framework-deprecated DEPRECATED: please use "team-core-platform" instead

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants