dotnet/wpf · warning · InvalidOperationException
Microsoft.Windows.Controls.SR.UIA_OperationCannotBePerformed
Error message
Microsoft.Windows.Controls.SR.UIA_OperationCannotBePerformed
What it means
Inside IExpandCollapseProvider.Expand, the peer has realized the RibbonMenuItem but verifies the item can actually expand: its Role must be TopLevelHeader or SubmenuHeader and it must have items. A leaf menu item (or an empty header) cannot expand, so the peer throws InvalidOperationException with SR.UIA_OperationCannotBePerformed.
Solutions
- Only call Expand on menu items that act as headers with children; check the item's role/items first via the RibbonMenuItem API or the automation tree.
- Read ExpandCollapseState instead of calling Expand for leaf items - they are always Collapsed and not expandable.
- Catch InvalidOperationException around Expand and treat it as 'item has no submenu'.
- Restructure ribbon data so header items always contain items if expandability is expected.
Example fix
// before
expandCollapsePattern.Expand();
// after
if (menuItem.HasItems && (menuItem.Role == MenuItemRole.TopLevelHeader || menuItem.Role == MenuItemRole.SubmenuHeader))
expandCollapsePattern.Expand(); Defensive patterns
Strategy: validation
Validate before calling
bool canExpand = menuItem.HasItems && (menuItem.Role == MenuItemRole.TopLevelHeader || menuItem.Role == MenuItemRole.SubmenuHeader);
Type guard
var header = owner as RibbonMenuItem; if (header != null && header.HasItems && header.HasItems) { /* expandable */ } Prevention
- Check Role and HasItems before Expand
- Read ExpandCollapseState for leaf items instead of expanding them
- Skip non-header items in automation sweeps
When it happens
Trigger: Calling Expand() on a RibbonMenuItem whose MenuItemRole is TopLevelItem or SubmenuItem (no submenu), or on a header item whose HasItems is false.
Common situations: Test suites iterating all ribbon menu items and calling Expand on each; applications where ribbon categories contain only leaf items so headers have no children.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Microsoft.Windows.Controls.SR.VirtualizedElement
- SR.Automation_RecursivePublicCall
- VirtualizedElement
- ' ' can only host a ' ' or a ' '. ' ' is an invalid…
- ' ' can only host a ' ' or a ' '. ' ' is an invalid…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/97b1c7402dc7f94e.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/System.Windows.Controls.Ribbon/Microsoft/Windows/Automation/Peers/RibbonMenuItemDataAutomationPeer.cs:151
{
if (!IsEnabled())
throw new ElementNotEnabledException();
UIElement owner = GetWrapper();
if (owner == null)
{
throw new ElementNotAvailableException(Microsoft.Windows.Controls.SR.VirtualizedElement);
}
RibbonMenuItem menuItemOwner = owner as RibbonMenuItem;
if (menuItemOwner != null)
{
MenuItemRole role = menuItemOwner.Role;
if ((role != MenuItemRole.TopLevelHeader && role != MenuItemRole.SubmenuHeader)
|| !menuItemOwner.HasItems)
{
throw new InvalidOperationException(Microsoft.Windows.Controls.SR.UIA_OperationCannotBePerformed);
}
menuItemOwner.IsSubmenuOpen = true;
}
else
{
throw new InvalidOperationException(Microsoft.Windows.Controls.SR.UIA_OperationCannotBePerformed);
}
}
///
void IExpandCollapseProvider.Collapse()
{
if (!IsEnabled())
throw new ElementNotEnabledException();
UIElement owner = GetWrapper();
if (owner == null)View on GitHub (pinned to 81131a70a4)