Skip to content

fix(accounts-controller): guard undefined scopes in multichain listing - #9877

Open
rajanpanth wants to merge 1 commit into
MetaMask:mainfrom
rajanpanth:fix/accounts-controller-scopes-guard
Open

fix(accounts-controller): guard undefined scopes in multichain listing#9877
rajanpanth wants to merge 1 commit into
MetaMask:mainfrom
rajanpanth:fix/accounts-controller-scopes-guard

Conversation

@rajanpanth

@rajanpanth rajanpanth commented Aug 14, 2026

Copy link
Copy Markdown

Summary

Adds a guard for undefined scopes when listing multichain accounts in the accounts controller flow.

Why

Undefined scope payloads can surface in edge cases and currently trigger avoidable runtime failures.


Note

Low Risk
Small defensive guard in account listing with a regression test; behavior change is only to skip malformed legacy accounts rather than throw.

Overview
listMultichainAccounts no longer crashes when persisted internal accounts are missing a scopes array (legacy or partial migration). Chain-filtered listing now requires Array.isArray(account.scopes) before calling isScopeEqualToAny, so those accounts are omitted from scoped results instead of causing a TypeError.

A regression test covers mixed state (normal account plus scopes: undefined), and the package changelog documents the fix (#41962).

Reviewed by Cursor Bugbot for commit c7261bf. Bugbot is set up for automated code reviews on this repo. Configure here.

@rajanpanth
rajanpanth requested review from a team as code owners August 14, 2026 04:40
@rajanpanth
rajanpanth force-pushed the fix/accounts-controller-scopes-guard branch from 43bdbf6 to 92323a4 Compare August 15, 2026 03:49
…ltichainAccounts`

`listMultichainAccounts(chainId)` filters accounts with
`isScopeEqualToAny(chainId, account.scopes)`, which calls `scopes.some(...)`.
`InternalAccount.scopes` is typed as required, but a legacy or partially
migrated account can be persisted without it, so `account.scopes` can be
`undefined` at runtime and throws a `TypeError`.

Guard the filter with `Array.isArray(account.scopes)` before matching. An
account without a valid `scopes` array declares no chain and is excluded from
chain-filtered results instead of throwing; unfiltered `listMultichainAccounts()`
is unchanged.
@rajanpanth
rajanpanth force-pushed the fix/accounts-controller-scopes-guard branch from 92323a4 to c7261bf Compare September 1, 2026 05:54
@rajanpanth

Copy link
Copy Markdown
Author

Rebased onto main (107 commits) and this is mergeable again.

The conflict was only in packages/accounts-controller/CHANGELOG.md: 39.1.1 was cut in the meantime, so my entry now sits under [Unreleased] with the released section untouched below it.

Since that is a lot of drift, I re-verified the fix rather than assuming it survived:

  • yarn workspace @metamask/accounts-controller run test passes, coverage 100% statements / 100% lines.
  • Reverting just the guard fails exactly one test, listMultichainAccounts > does not throw when an account has an undefined scopes field and excludes it from chain-filtered results, so the test still pins the behaviour rather than passing incidentally.

The change itself is unchanged in substance, an Array.isArray guard before isScopeEqualToAny so a legacy or partially-migrated account persisted without scopes is skipped instead of throwing a TypeError.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant