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
- Wrap GetPropertyValue in try/catch for ElementNotAvailableException and treat the element as gone.
- Re-resolve the element via UIA's fresh element-from-handle/point before reading properties.
- 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
- Catch ElementNotAvailableException around every cross-process property read.
- Use UIA CacheRequest to fetch properties atomically.
- Re-resolve elements rather than reusing stale AutomationElement references across waits.
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
- ArgumentNullException (hwnd)
- Invalid type specified for AutomationIdentifier
- ' ' is not a valid value for this control.
- 0x80070057
- ArgumentNullException (buffer/sourceBuffer was IntPtr.Zero)
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)