dotnet/wpf · error · ElementNotEnabledException
UIA_E_ELEMENTNOTENABLED
UIA_E_ELEMENTNOTENABLED
Error message
description (from UiaGetErrorDescription or SR.UnknownCoreAPIError)
What it means
UiaCoreApi translates HRESULTs returned by the native UI Automation Core into the corresponding WPF UIAutomation client exceptions. When the core returns UIA_E_ELEMENTNOTENABLED, the WrapNativeExceptionIfRequired path throws ElementNotEnabledException with a description obtained via UiaGetErrorDescription (or a fallback 'unknown error' string). It means the automation operation targeted a control that exists but is currently disabled (not interactive).
Solutions
- Before interacting, check the IsEnabled property of the AutomationElement and wait until it is true (poll or subscribe to the IsEnabled property-changed event)
- Fix the automation flow to enable the control first (fill required fields, complete prerequisite steps) in the app under test
- Catch ElementNotEnabledException and retry after a delay if the UI may enable the element shortly
- If the element should be enabled but is not, investigate the target application's enable/disable logic
Example fix
// before
invokePattern.Invoke();
// after
if (button.Current.IsEnabled)
{
invokePattern.Invoke();
} Defensive patterns
Strategy: validation
Validate before calling
if (!element.Current.IsEnabled)
{
// wait/poll until enabled, or fail fast with a clear message
WaitForEnabled(element, timeout: TimeSpan.FromSeconds(5));
} Type guard
static bool IsInteractive(AutomationElement e) => e.Current.IsEnabled && !e.Current.IsOffscreen;
Try / catch
try { invokePattern.Invoke(); }
catch (ElementNotEnabledException) { RetryAfterDelayOrAbort(); } Prevention
- Check IsEnabled before every interaction
- Subscribe to IsEnabled property-changed events instead of polling
- Build waits into UI test helpers for asynchronously-enabled controls
When it happens
Trigger: Calling any UIA client operation (e.g. AutomationElement pattern invocation, InvokePattern.Invoke) that performs a native UIA call which fails with HRESULT UIA_E_ELEMENTNOTENABLED (0x80040200) on a disabled element.
Common situations: Automating a button/menu item that is disabled until form fields are filled; clicking controls in a wizard step that has not been enabled yet; UI tests racing against the app enabling controls after async validation.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/558c4c5e611f4eb2.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/MS/Internal/Automation/UiaCoreApi.cs:1188
{
return;
}
// Handle these UIA exceptions specially - COM Interop
// maps others (eg. InvalidArgument), but not these:
if (hr == UIA_E_ELEMENTNOTENABLED
|| hr == UIA_E_ELEMENTNOTAVAILABLE
|| hr == UIA_E_NOCLICKABLEPOINT
|| hr == UIA_E_PROXYASSEMBLYNOTLOADED)
{
string description;
if (!UiaGetErrorDescription(out description))
description = SR.UnknownCoreAPIError;
switch (hr)
{
case UIA_E_ELEMENTNOTENABLED:
throw new ElementNotEnabledException(description);
case UIA_E_ELEMENTNOTAVAILABLE:
throw new ElementNotAvailableException(description);
case UIA_E_NOCLICKABLEPOINT:
throw new NoClickablePointException(description);
case UIA_E_PROXYASSEMBLYNOTLOADED:
throw new ProxyAssemblyNotLoadedException(description);
}
}
// Not a UIA-specific exception - let COM Interop handle the rest.
// (Marshal.ThrowExceptionForHR automatically calls GetErrorInfo to fill in the description
// field - UIA sets the error info itself, so it will get propogated here.)
Marshal.ThrowExceptionForHR(hr);
}
View on GitHub (pinned to 81131a70a4)