dotnet/wpf · error · ElementNotAvailableException
new ElementNotAvailableException()
Error message
new ElementNotAvailableException()
What it means
GetAccessibleChildren throws ElementNotAvailableException when the Win32 AccessibleChildren call returns E_INVALIDARG. The wrapper treats this as evidence the accessible object is no longer available/valid (child enumeration impossible), which in UIA terms means the element is dead.
Solutions
- Catch ElementNotAvailableException during tree traversal and treat the element as removed — rescan from the root.
- Re-query the element/children promptly after obtaining childCount to shrink the race window; add retries with delay.
- Use UIA's raw view walker / TreeWalker instead of direct MSAA enumeration where possible, as it handles dynamic trees better.
- If the target app is yours, ensure its IAccessible get_accChildCount/get_accChild agree and keep objects alive during enumeration.
Example fix
// before
var children = GetAccessibleChildren(accessible); // element died mid-call
// after
try { var children = GetAccessibleChildren(accessible); }
catch (ElementNotAvailableException)
{
accessible = null; // element no longer available; rescan tree
} Defensive patterns
Strategy: try-catch
Validate before calling
int count = accessible.ChildCount; // re-read and re-validate immediately before enumerating children; abort if the element reports 0 or the window is gone
Try / catch
try
{
var children = GetAccessibleChildren(accessible);
}
catch (ElementNotAvailableException)
{
// element vanished mid-enumeration; rescan the tree from the root
accessible = null;
RetryTreeWalk();
} Prevention
- Wrap every child-enumeration step in ElementNotAvailableException handling
- Rescan from the root instead of reusing stale accessible references
- Minimize delay between ChildCount and AccessibleChildren calls
- On heavily dynamic UIs, prefer UIA TreeWalker over MSAA child enumeration
- Retry the walk a bounded number of times with small delays before giving up
When it happens
Trigger: Enumerating children of an MSAA accessible whose childCount changed or whose underlying object was destroyed between querying Accessible.ChildCount and calling AccessibleChildren; passing an accessible object from a closed window/control.
Common situations: Walking UI trees of apps that rebuild controls dynamically (toolbars, virtualized lists, browser content); timing races where the container is reparented or destroyed during traversal; legacy MSAA apps with buggy child-count reporting.
Related errors
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/aa9d02d383402181.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/Accessible.cs:917
// Returns an array of IAccessible interfaces and/or childID's representing the children
internal static object[] GetAccessibleChildren(IAccessible accessibleObject, out int childrenReturned)
{
int childCount;
object[] aChildren = null;
try
{
childCount = accessibleObject.accChildCount;
childrenReturned = 0;
if (childCount > 0)
{
aChildren = new object[childCount];
// Get the raw children because accNavigate doesn't work
if (UnsafeNativeMethods.AccessibleChildren(accessibleObject, 0, childCount, aChildren, out childrenReturned) == NativeMethods.E_INVALIDARG)
{
System.Diagnostics.Debug.Fail("Call to AccessibleChildren() returned E_INVALIDARG.");
throw new ElementNotAvailableException();
}
}
return aChildren;
}
catch (Exception e)
{
if (HandleIAccessibleException(e))
{
throw;
}
throw new ElementNotAvailableException();
}
}
#endregion
#endregion Internal MethodsView on GitHub (pinned to 81131a70a4)