Skip to content

MudMenu: Fix mutation-unsafe async enumeration during close#12757

Merged
danielchalmers merged 7 commits intoMudBlazor:devfrom
danielchalmers:menu-nested-12741
Feb 28, 2026
Merged

MudMenu: Fix mutation-unsafe async enumeration during close#12757
danielchalmers merged 7 commits intoMudBlazor:devfrom
danielchalmers:menu-nested-12741

Conversation

@danielchalmers
Copy link
Member

@danielchalmers danielchalmers commented Feb 27, 2026

Fixes mutation-unsafe async enumeration in MudMenu:

  • CloseMenuAsync() now snapshots open children before await:
    • _subMenus.Where(...).ToArray()
  • OpenSubMenuAsync() now snapshots open siblings before await:
    • ParentMenu._subMenus.Where(...).ToArray()

This prevents InvalidOperation_EnumFailedVersion when child menus unregister/dispose while close recursion is running.

Fixes #12741

Checklist:

  • I've read the contribution guidelines
  • My code follows the style of this project
  • I've added or updated relevant unit tests

…c guard test for the mutation race.

### What I changed

- Fixed mutation-unsafe async enumeration in `MudMenu`:
  - [MudMenu.razor.cs](/mnt/f/source/repos/MudBlazor/src/MudBlazor/Components/Menu/MudMenu.razor.cs)
  - `CloseMenuAsync()` now snapshots open children before `await`:
    - `_subMenus.Where(...).ToArray()`
  - `OpenSubMenuAsync()` now snapshots open siblings before `await`:
    - `ParentMenu._subMenus.Where(...).ToArray()`

This prevents `InvalidOperation_EnumFailedVersion` when child menus unregister/dispose while close recursion is running.

- Added a deterministic regression unit test (not navigation-timing dependent):
  - [MenuTests.cs](/mnt/f/source/repos/MudBlazor/src/MudBlazor.UnitTests/Components/MenuTests.cs)
  - New test: `CloseMenu_UnregisteringChildDuringClose_DoesNotThrow`
  - It forces child unregister during `CloseMenuAsync()` and asserts no throw.
  - Includes a local `BlockingKeyInterceptorService` test double to create the race window deterministically.

- Kept the viewer repro and clarified docs wording:
  - [MenuNestedNavigationHrefTest.razor](/mnt/f/source/repos/MudBlazor/src/MudBlazor.UnitTests.Viewer/TestComponents/Menu/MenuNestedNavigationHrefTest.razor)
  - Updated comments/description to say there is no **navigation-driven** bUnit test for that exact browser-timing repro.

### Validation

I could not run `dotnet build/test` in this environment because `dotnet` is not installed (`dotnet: command not found`).
@mudbot mudbot bot changed the title Menu-nested-12741 MudMenu: Fix mutation-unsafe async enumeration during close Feb 27, 2026
@mudbot mudbot bot added bug Unexpected behavior or functionality not working as intended regression Previously worked and now doesn't labels Feb 27, 2026
@danielchalmers danielchalmers merged commit 7fea223 into MudBlazor:dev Feb 28, 2026
18 of 19 checks passed
@danielchalmers danielchalmers deleted the menu-nested-12741 branch February 28, 2026 00:24
This was referenced Mar 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Unexpected behavior or functionality not working as intended regression Previously worked and now doesn't

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MudMenuItem: Nested menus throw InvalidOperationException during navigation

2 participants