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

  1. Resize the target window/toolbar (or collapse overflowing UI) so the button is fully visible before invoking.
  2. Re-find the element right before invoking, since the hidden state can change at any time.
  3. If the button lives in the overflow chevron, invoke the chevron first or use the element exposed for the overflow area.
  4. 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

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


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)