dotnet/wpf · error · InvalidOperationException
SR.OperationCannotBePerformed
Error message
SR.OperationCannotBePerformed
What it means
WindowsToolbar's Invoke provider clicks a toolbar button by simulating a mouse click at the button's center. Before clicking it checks TB_ISBUTTONHIDDEN; if the button is reported hidden, the click cannot land on it, so an InvalidOperationException(SR.OperationCannotBePerformed) is thrown. UIA providers throw this when the requested operation is not currently possible for the element's live state.
Solutions
- Resize the target window/toolbar (or collapse overflowing UI) so the button is fully visible before invoking.
- Re-find the element right before invoking, since the hidden state can change at any time.
- If the button lives in the overflow chevron, invoke the chevron first or use the element exposed for the overflow area.
- Catch InvalidOperationException and retry after making the element visible.
Example fix
// before
button.Invoke(); // throws if hidden
// after
var rect = button.Current.BoundingRectangle;
if (rect.Width == 0 || rect.Height == 0)
window.SetWindowPosition/resize or open the overflow first;
button.Invoke(); Defensive patterns
Strategy: validation
Validate before calling
var r = button.Current.BoundingRectangle;
if (r.IsEmpty || !button.Current.IsEnabled) throw new SkipException("toolbar button not clickable now"); Type guard
bool IsInvokable(AutomationElement e) => e.Current.IsEnabled && !e.Current.BoundingRectangle.IsEmpty;
Try / catch
try { button.Invoke(); }
catch (InvalidOperationException) { /* make visible / resize window, then retry once */ } Prevention
- Check BoundingRectangle is non-empty before invoking toolbar buttons
- Handle toolbar overflow/chevron layout before automation
- Re-find elements immediately before invoking since state changes anytime
When it happens
Trigger: Calling Invoke() (InvokePattern) on a toolbar button proxy whose underlying Win32 button returns nonzero for TB_ISBUTTONHIDDEN (e.g. the toolbar was resized so the button overflowed into a chevron, or the button is otherwise hidden).
Common situations: Automating toolbars in windows that are too small, toolbars with overflow/chevron areas, or tests running against a UI whose layout changed between locating the element and invoking it.
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
- Element is not enabled.
- ' ' is not a valid value for this control.
- Element is not enabled.
- Element is not enabled.
- ElementNotAvailableException
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/6e724093be815b34.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/WindowsToolbar.cs:652
{
IntPtr hwndToolTip = Misc.ProxySendMessage(_hwnd, NativeMethods.TB_GETTOOLTIPS, IntPtr.Zero, IntPtr.Zero);
return Misc.GetItemToolTipText(_hwnd, hwndToolTip, _idCommand);
}
private void Invoke()
{
// Make sure that the toolbar is enabled, and that the toolbar button is enabled.
if (!SafeNativeMethods.IsWindowEnabled(_hwnd)
|| Misc.ProxySendMessageInt(_hwnd, NativeMethods.TB_ISBUTTONENABLED, new IntPtr(_idCommand), IntPtr.Zero) == 0)
{
throw new ElementNotEnabledException();
}
// Check that button can be clicked (button not hidden)
// This state could change anytime so success is not guaranteed
if (Misc.ProxySendMessageInt(_hwnd, NativeMethods.TB_ISBUTTONHIDDEN, new IntPtr(_idCommand), IntPtr.Zero) != 0)
{
throw new InvalidOperationException(SR.OperationCannotBePerformed);
}
// Click the center of the button
// TB_CHECKBUTTON and TB_PRESSBUTTON messages are not used as they will not trigger proper notifications
// Need to check that this button is visible to the mouse
Rect boundingRectangle = BoundingRectangle;
if (boundingRectangle.IsEmpty)
{
throw new InvalidOperationException(SR.OperationCannotBePerformed);
}
// make sure this item is active
SetFocus();
Misc.MouseClick(((int)boundingRectangle.Left + (int)boundingRectangle.Right) / 2, ((int)boundingRectangle.Top + (int)boundingRectangle.Bottom) / 2);
}
View on GitHub (pinned to 81131a70a4)