dotnet/wpf · error · ElementNotAvailableException

ElementNotAvailableException

Error message

ElementNotAvailableException

What it means

HwndProxyElementProvider.GetPropertyValue throws ElementNotAvailableException when SafeNativeMethods.GetWindowThreadProcessId fails (returns 0), meaning the underlying HWND is no longer valid — the element has disappeared, so no property (here ProcessIdProperty) can be retrieved.

Solutions

  1. Wrap GetPropertyValue in try/catch for ElementNotAvailableException and treat the element as gone.
  2. Re-resolve the element via UIA's fresh element-from-handle/point before reading properties.
  3. Use cache requests (BuildUpdatedCache) to fetch properties atomically in one cross-process call.

Example fix

// before
int pid = (int)element.GetCurrentPropertyValue(AutomationElement.ProcessIdProperty);
// after
try { int pid = (int)element.GetCurrentPropertyValue(AutomationElement.ProcessIdProperty); }
catch (ElementNotAvailableException) { /* window closed; re-enumerate */ }
Defensive patterns

Strategy: try-catch

Validate before calling

if (!SafeNativeMethods.IsWindow(hwnd))
    throw new ElementNotAvailableException(); // element gone before property fetch

Type guard

static bool IsElementAvailable(AutomationReference e) => e != null && SafeNativeMethods.IsWindow(e.Hwnd);

Try / catch

try { pid = (int)element.GetCurrentPropertyValue(AutomationElement.ProcessIdProperty); }
catch (ElementNotAvailableException) { ReenumerateWindows(); }

Prevention

When it happens

Trigger: Calling GetPropertyValue(ProcessIdProperty) (or any property reaching this path) after the target window was destroyed; GetWindowThreadProcessId returns 0 because the HWND is stale.

Common situations: Automation runs against apps that close windows mid-scan; UIA clients enumerating desktop windows racing with app shutdown; flaky UI test suites when a dialog dismisses between enumeration and property fetch.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/MS/Internal/Automation/HwndProxyElementProvider.cs:146

                    str[0] = '\0';
                }

                // get rid of any & used for shortcut keys
                return Misc.StripMnemonic(str.ToString());
            }
            else if (idProp == AutomationElement.IsEnabledProperty)
            {
                return IsWindowReallyEnabled( _hwnd );
            }
            else if (idProp == AutomationElement.ProcessIdProperty)
            {
                // Get the pid of the process that the HWND lives in, not the
                // pid that this proxy lives in
                int pid;
                // GetWindowThreadProcessId does use SetLastError().  So a call to GetLastError() would be meanless.
                if (SafeNativeMethods.GetWindowThreadProcessId(_hwnd, out pid) == 0)
                {
                    throw new ElementNotAvailableException();
                }

                return pid;
            }
            else if( idProp == AutomationElement.NativeWindowHandleProperty )
            {
                // Need to downcast to Int32, since IntPtr's are not remotable.
                return ((IntPtr) _hwnd).ToInt32();
            }
            else if (idProp == AutomationElement.HasKeyboardFocusProperty)
            {
                SafeNativeMethods.GUITHREADINFO gti = new SafeNativeMethods.GUITHREADINFO ();

                if (!Misc.GetGUIThreadInfo(0, ref gti))
                {
                    return false;
                }

View on GitHub (pinned to 81131a70a4)