dotnet/wpf · error · ElementNotEnabledException

Element is not enabled.

Error message

Element is not enabled.

What it means

ElementNotEnabledException ('Element is not enabled.') is thrown by the WindowsButton proxy's Invoke() when SafeNativeMethods.IsWindowEnabled(_hwnd) reports the underlying Win32 window is disabled. The button's enabled state can change at any moment between the check and the click, which the code explicitly notes; the UIA contract requires invoking a disabled element to fail with this exception. It is a standard UIA provider-side state guard, not a defect.

Solutions

  1. Check IsEnabled on the AutomationElement (or wait for the enabled state) before calling Invoke, e.g. poll until element.Current.IsEnabled.
  2. Retry the Invoke after a short delay if the button is expected to become enabled, since the state can change anytime.
  3. Update the UI state the button depends on (fill required fields, close the modal) so the app enables the button.
  4. Catch ElementNotEnabledException around Invoke and treat it as button-currently-disabled in the automation flow.

Example fix

// before
var invoke = button.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
invoke.Invoke();
// after
var invoke = button.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
var deadline = DateTime.UtcNow.AddSeconds(5);
while (!button.Current.IsEnabled && DateTime.UtcNow < deadline)
    Thread.Sleep(200);
if (button.Current.IsEnabled)
    invoke.Invoke();
Defensive patterns

Strategy: retry

Validate before calling

// C# (UIA client)
bool enabled = element.Current.IsEnabled;
// invoke only when enabled; otherwise wait or update app state first

Try / catch

try
{
    var inv = element.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
    inv.Invoke();
}
catch (ElementNotEnabledException)
{
    // button disabled; wait for it to become enabled or fail the step
}

Prevention

When it happens

Trigger: Calling InvokePattern.Invoke() (or the internal Invoke path used by SelectionItem special cases) on a WindowsButton whose hwnd is disabled (EnableWindow(false), control.Enabled=false in WinForms, or a modal owner blocking the button).

Common situations: Test automation clicking buttons during a modal operation (busy cursor, progress dialog) when the app disabled its UI; automation racing a validation flow that disables the button until input is complete; stale references after the app re-enabled/disabled controls.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/86aa8c3afe190c09. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/WindowsButton.cs:463

        };

        #endregion

        // ------------------------------------------------------
        //
        // Private Methods
        //
        // ------------------------------------------------------

        #region Private Methods

        private void Invoke()
        {
            // Check that button can be clicked
            // This state could change anytime
            if (!SafeNativeMethods.IsWindowEnabled(_hwnd))
            {
                throw new ElementNotEnabledException();
            }

            // Moved this outside the if block because it's needed for WinForms, which uses _acc.DoDefaultAction()
            if (!IsShowAllProgramsButton())
            {
                // SetFocus is needed here to workaround a bug
                Misc.SetFocus(_hwnd);
            }

            if (_acc == null)
            {
                switch (_style)
                {
                    case NativeMethods.BS_PUSHBUTTON:
                    case NativeMethods.BS_DEFPUSHBUTTON:
                    case NativeMethods.BS_PUSHBOX:
                    case NativeMethods.BS_OWNERDRAW:
                    case NativeMethods.BS_USERBUTTON:

View on GitHub (pinned to 81131a70a4)