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
- Check IsEnabled on the AutomationElement (or wait for the enabled state) before calling Invoke, e.g. poll until element.Current.IsEnabled.
- Retry the Invoke after a short delay if the button is expected to become enabled, since the state can change anytime.
- Update the UI state the button depends on (fill required fields, close the modal) so the app enables the button.
- 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
- Poll element.Current.IsEnabled with a timeout before Invoke.
- Ensure the app state that gates the button (validation, modal) is satisfied before automating.
- Retry Invoke with backoff because the enabled state can change anytime.
- Catch ElementNotEnabledException at the interaction layer so a transient disable does not abort the whole run.
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
- ElementNotEnabledException
- ElementNotEnabledException
- SR.OperationCannotBePerformed
- ' ' is not a valid value for this control.
- Element is not enabled.
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)