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

  1. Wrap access to element properties/patterns in try-catch for ElementNotAvailableException and treat it as 'element gone'
  2. Re-resolve the element freshly from the desktop/app window instead of reusing cached references
  3. Subscribe to the WindowClosed / structure-changed events and drop cached elements when they fire
  4. 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

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 methods

View on GitHub (pinned to 81131a70a4)