dotnet/wpf · warning · ElementNotAvailableException
ElementNotAvailableException
Error message
ElementNotAvailableException
What it means
GetParent on an MSAA-backed element is only valid below a window boundary; if the element's accessible role is Window, walking up would escape the automation 'window', so the provider throws ElementNotAvailableException. The UIA element has become invalid for navigation (its parent is out of scope).
Solutions
- Stop the upward walk when the element's CurrentControlType is Window/Pane or when AutomationElement.RootElement is reached
- Compare the element against AutomationElement.RootElement before requesting its parent
- Re-walk from RootElement using FindFirst/FindAll instead of walking up from a stale element
- Catch ElementNotAvailableException and treat it as 'reached the top of the scope' rather than a failure
Example fix
// before
while (e != null) { Process(e); e = walker.GetParent(e); }
// after
while (e != null && !Equals(e, AutomationElement.RootElement))
{
if ((int)e.GetCurrentPropertyValue(AutomationElement.ControlTypeProperty)
== ControlType.Window.Id) break; // window boundary: stop walking up
Process(e);
e = walker.GetParent(e);
} Defensive patterns
Strategy: try-catch
Validate before calling
if (element == AutomationElement.RootElement || element.Current.ControlType == ControlType.Window) return null; // top of walk
Type guard
static bool IsWindowRoot(AutomationElement e) => e.Current.ControlType == ControlType.Window || e == AutomationElement.RootElement;
Try / catch
try { parent = walker.GetParent(element); }
catch (ElementNotAvailableException) { parent = null; /* reached window boundary */ } Prevention
- Stop upward walks at Window control type or RootElement
- Avoid cached tree references after UI restructure
- Re-resolve elements from the root after navigation changes
When it happens
Trigger: Calling TreeWalker.RawViewWalker/ControlViewWalker GetParent (or the Parent property) on an element whose accessible Role == AccessibleRole.Window — i.e. asking for the parent of a window root that is not the UIA root element.
Common situations: Walking up from a top-level window or dialog expecting to reach the desktop element; cached tree walks done after UI restructuring where the former child now behaves as a window root; custom proxies reporting Window role unexpectedly.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- SR.VirtualizedElement
- ArgumentOutOfRangeException
- Element no longer available.
- ElementNotAvailableException
- ElementNotAvailableException
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/fc71289f3722e61b.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/MSAANativeProvider.cs:1029
// note: _controlType can stay null. in that case we'll try to figure it out each time.
// if this is a performance problem we can add a separate boolean flag to indicate whether
// we have computed the control type.
}
// return the cached value
return _controlType;
}
}
private Accessible GetParent()
{
// this should never be called on a root.
Debug.Assert(!IsRoot);
// we should never step up out of a "window". we should hit the root first.
if (_acc.Role == AccessibleRole.Window)
{
throw new ElementNotAvailableException();
}
Accessible parentAccessible = _acc.Parent;
// if we get a null parent (Accessible.Parent will return null for IAccessible's
// when we detect bad navigation) then we have no idea where we are. bail.
if (parentAccessible == null)
{
throw new ElementNotAvailableException();
}
return parentAccessible;
}
// The following classes are known to have bad IAccessible implementation (eg.
// overly complex structure or too many problems for the proxy to deal with).
// Note that while similar "bad lists" are used by UIACore and the proxy manager,View on GitHub (pinned to 81131a70a4)