dotnet/wpf · warning · ElementNotAvailableException

ElementNotAvailableException(e)

Error message

ElementNotAvailableException(e)

What it means

HandleIAccessibleException converts COMExceptions whose HRESULT is E_POINTER (returned as a NullReferenceException by the wrapper) into ElementNotAvailableException with the original exception attached. Badly-implemented IAccessible servers (e.g. Media Player) return E_POINTER for ordinary failures; in this process it never indicates a real null dereference, so the provider reclassifies it as 'element not available' rather than crashing the client with NullReferenceException.

Solutions

  1. Catch ElementNotAvailableException (not NullReferenceException) around UIA calls against such apps and re-find the element
  2. Retry the query once after a short delay — these servers often fail only in transient states
  3. Poll element availability (TryGetClickablePoint / Current failures) before reading many properties
  4. Prefer UIA Core over MSAA proxy path for such apps if possible (UseHttpDelegate / newer provider) to avoid the bad IAccessible

Example fix

// before
try { name = element.Current.Name; }
catch (NullReferenceException) { name = null; } // wrong: NRE is reclassified
// after
try { name = element.Current.Name; }
catch (ElementNotAvailableException) {
    element = FindElementAgain();
    name = element?.Current.Name;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Probe cheaply before bulk reads against flaky MSAA servers
try { var _ = element.Current.Name; }
catch (ElementNotAvailableException) { element = FindElementAgain(); }

Type guard

static bool IsUsable(AutomationElement e) {
    try { var _ = e.Current.AutomationId; return true; }
    catch (ElementNotAvailableException) { return false; }
    catch (InvalidOperationException) { return false; }
}

Try / catch

try {
    name = element.Current.Name;
} catch (ElementNotAvailableException ex)
    when (ex.InnerException is NullReferenceException) {
    // server returned E_POINTER; re-find and retry once
    element = FindElementAgain();
    name = element?.Current.Name;
}

Prevention

When it happens

Trigger: Any IAccessible property/method call on a server (Media Player and similar) that returns COM error E_POINTER, surfacing as NullReferenceException in the wrapper and being converted to ElementNotAvailableException(e).

Common situations: Automating media players or other apps whose MSAA servers return E_POINTER when queried during playback state changes; UIA scripts reading properties of elements in transient states; interop layers that surface COM errors as NREs.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/Accessible.cs:1301

        // or returns true indicating the caller should rethrow the exception.
        private static bool HandleIAccessibleException(Exception e)
        {
            if (e is OutOfMemoryException)
            {
                // Some OLEACC proxies produce out-of-memory for non-critical reasons:
                // notably, the treeview proxy will raise this if the target HWND no longer exists,
                // GetWindowThreadProcessID fails and it therefore won't be able to allocate shared
                // memory in the target process, so it incorrectly assumes OOM.
                // (Need to check this before Misc.IsCriticalException, since it includes OOM as critical.)
                throw new ElementNotAvailableException(e);
            }

            if (e is NullReferenceException)
            {
                // Media Player and some other badly-implemented IAccessibles can return the correponding 
                // COM error code (E_POINTER).  This does not actually indicate a null dereference in this 
                // process.
                throw new ElementNotAvailableException(e);
            }

            if (Misc.IsCriticalException(e))
            {
                return true;
            }

            COMException comException = e as COMException;

            if (e is NotImplementedException)
            {
                // just return on E_NOTIMPL errors
                return false;
            }
            else if (comException != null)
            {
                // convert certain COM exceptions to ElementNotAvailable exceptions.
                // these occur when the underlying UI elements disappear but we are still

View on GitHub (pinned to 81131a70a4)