dotnet/wpf · error · ElementNotAvailableException
UIA_E_ELEMENTNOTAVAILABLE
UIA_E_ELEMENTNOTAVAILABLE
Error message
description (from UiaGetErrorDescription or SR.UnknownCoreAPIError)
What it means
UiaCoreApi maps the native HRESULT UIA_E_ELEMENTNOTAVAILABLE to ElementNotAvailableException. This is thrown when an automation element that the client held a reference to is no longer available - the underlying UI element was destroyed, closed, or its runtime ID is stale. UiaGetErrorDescription supplies the message.
Solutions
- Wrap access to element properties/patterns in try-catch for ElementNotAvailableException and treat it as 'element gone'
- Re-resolve the element freshly from the desktop/app window instead of reusing cached references
- Subscribe to the WindowClosed / structure-changed events and drop cached elements when they fire
- Reduce reliance on stale references in event handlers: re-find the element by AutomationId at handling time
Example fix
// before
var name = cachedItem.Current.Name;
// after
try { var name = cachedItem.Current.Name; }
catch (ElementNotAvailableException) { cachedItem = FindFreshItem(); } Defensive patterns
Strategy: try-catch
Validate before calling
// No reliable pre-check; validate element is alive just before use if (element.GetRuntimeId() == null) ReacquireElement();
Type guard
static bool IsAlive(AutomationElement e) { try { var _ = e.Current.Name; return true; } catch (ElementNotAvailableException) { return false; } } Try / catch
try { var name = element.Current.Name; }
catch (ElementNotAvailableException) { element = ReacquireElement(); } Prevention
- Never cache AutomationElement references across UI structure changes
- Re-find elements by AutomationId at point of use
- Drop references on WindowClosed/structure-changed events
When it happens
Trigger: Any native UIA call made through a stale AutomationElement reference that returns UIA_E_ELEMENTNOTAVAILABLE (0x80040201), e.g. accessing Current properties or invoking a pattern on an element after its window closed or the item was removed from a list.
Common situations: Holding AutomationElement references across UI rebuilds (lists/virtualized grids recycle items); reacting to an event from an element whose window then closes; menu items that disappear between hooking and invoking.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/4afc62b9930a6137.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/MS/Internal/Automation/UiaCoreApi.cs:1191
// 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);
}
#endregion Private Methods
#region Raw API methodsView on GitHub (pinned to 81131a70a4)