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

  1. Catch ElementNotAvailableException during tree traversal and treat the element as removed — rescan from the root.
  2. Re-query the element/children promptly after obtaining childCount to shrink the race window; add retries with delay.
  3. Use UIA's raw view walker / TreeWalker instead of direct MSAA enumeration where possible, as it handles dynamic trees better.
  4. 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

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 Methods

View on GitHub (pinned to 81131a70a4)