dotnet/wpf · warning · ElementNotAvailableException

E_UNEXPECTED

E_UNEXPECTED

Error message

ElementNotAvailableException(e)

What it means

The IAccessible server returned E_UNEXPECTED and the provider translates it into ElementNotAvailableException. Per the code comment this means the MSAA server was released unexpectedly but still has pending events; if execution is inside one of the provider's event handlers it must be abandoned. It signals the accessible server object died mid-operation.

Solutions

  1. Catch ElementNotAvailableException in event handlers and exit the handler gracefully (the framework requires abandoning the context).
  2. Unregister event handlers (RemoveAutomationEventHandler) when the target window is closed rather than leaving them attached.
  3. Check whether the target application is crashing or leaking COM references; use AppVerifier/COM ref tracking if the server release is unexpected.
  4. Retry the operation after re-resolving the element tree; the element that owned the server is gone.

Example fix

// before
Automation.AddAutomationEventHandler(InvokePattern.InvokedEvent, win, TreeScope.Element,
    (s, e) => Process(e.Source.Current.Name)); // server released -> E_UNEXPECTED crash out of handler
// after
Automation.AddAutomationEventHandler(InvokePattern.InvokedEvent, win, TreeScope.Element,
    (s, e) =>
    {
        try { Process(e.Source.Current.Name); }
        catch (ElementNotAvailableException) { /* server released; abandon handler */ }
    });
Defensive patterns

Strategy: try-catch

Validate before calling

// Before relying on long-lived event subscriptions, confirm the target window is open:
bool TargetAlive(Process p) => !p.HasExited && p.MainWindowHandle != IntPtr.Zero;

Try / catch

try
{
    HandleEvent(e);
}
catch (ElementNotAvailableException)
{
    // server released with pending events: abandon this handler invocation
    return;
}

Prevention

When it happens

Trigger: An Accessible-wrapped IAccessible call (property read, navigation, or an event handler callback on the provider) after the native server was released — e.g. the hosting window/control was destroyed while MSAA events were still being dispatched.

Common situations: Applications closing windows during active AutomationEventHandler/AutomationFocusChanged callbacks; UIA clients holding AutomationEventHandlers registered on short-lived windows; crash or fast exit of the target app during event dispatch.

Related errors


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

Appendix: source

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

                        // GetWindowThreadProcessID fails and it therefore won't be able to allocate shared
                        // memory in the target process, so it incorrectly assumes OOM.
                        throw new ElementNotAvailableException(e);
                        
                    case NativeMethods.E_INVALIDARG:
                        // One or more arguments were invalid. This error occurs when the caller attempts to identify
                        // a child object using an identifier that the server does not recognize. This error also results
                        // when a client attempts to identify a child object within an object that has no children.
                        throw new ArgumentException(SR.InvalidParameter);

                    case NativeMethods.E_ACCESSDENIED:
                        // This is returned when you call get_accValue to get the value of a password control.
                        throw new UnauthorizedAccessException();

                    case NativeMethods.E_UNEXPECTED:
                        // An IAccessible server has been released unexpectedly but still has pending events.
                        // If the current execution context is inside one of these event handlers it must be 
                        // abandoned.
                        throw new ElementNotAvailableException(e);

                    default:
                        // we want to know when we get an exception we haven't seen before
                        Debug.Fail(string.Format(CultureInfo.CurrentCulture, "MsaaNativeProvider: IAccessible threw a COMException: {0}", e.Message));
                        break;
                }
            }
            else if (e is InvalidCastException)
            {
                // sometimes Trident throws InvalidCastExceptions on elements from obsolete pages
                throw new ElementNotAvailableException(e);
            }
            else if (e is BadImageFormatException)
            {
                // This control/window mostly has went away or is in the process of shutting down.
                throw new ElementNotAvailableException(e);
            }
            else

View on GitHub (pinned to 81131a70a4)