{"record":{"id":"ea803a3ba94af587","repo":"dotnet/wpf","slug":"new-elementnotavailableexception-e","errorCode":null,"errorMessage":"new ElementNotAvailableException(e)","messagePattern":"new ElementNotAvailableException\\(e\\)","errorType":"exception","errorClass":"ElementNotAvailableException","httpStatus":null,"severity":"warning","filePath":"src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/Accessible.cs","lineNumber":1293,"sourceCode":"\n            rect.right += rect.left;    // convert width to right\n            rect.bottom += rect.top;    // convert height to bottom\n            return rect;\n        }\n        \n        // converts the exception into a more appropriate one and throws it,\n        // or returns false indicating the caller should assume a default result\n        // or returns true indicating the caller should rethrow the exception.\n        private static bool HandleIAccessibleException(Exception e)\n        {\n            if (e is OutOfMemoryException)\n            {\n                // Some OLEACC proxies produce out-of-memory for non-critical reasons:\n                // notably, the treeview proxy will raise this if the target HWND no longer exists,\n                // GetWindowThreadProcessID fails and it therefore won't be able to allocate shared\n                // memory in the target process, so it incorrectly assumes OOM.\n                // (Need to check this before Misc.IsCriticalException, since it includes OOM as critical.)\n                throw new ElementNotAvailableException(e);\n            }\n\n            if (e is NullReferenceException)\n            {\n                // Media Player and some other badly-implemented IAccessibles can return the correponding \n                // COM error code (E_POINTER).  This does not actually indicate a null dereference in this \n                // process.\n                throw new ElementNotAvailableException(e);\n            }\n\n            if (Misc.IsCriticalException(e))\n            {\n                return true;\n            }\n\n            COMException comException = e as COMException;\n\n            if (e is NotImplementedException)","sourceCodeStart":1275,"sourceCodeEnd":1311,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/Accessible.cs#L1275-L1311","documentation":"Inside HandleIAccessibleException, a COMException with E_OUTOFMEMORY (or equivalent) is deliberately translated to ElementNotAvailableException with the original as inner exception. OLEACC proxies report out-of-memory for non-critical reasons — notably the treeview proxy when the target HWND no longer exists and shared memory cannot be allocated in the target process — so the provider reinterprets it as 'element not available'.","triggerScenarios":"Calling into an IAccessible whose OLEACC proxy fails to allocate shared memory in the target process because GetWindowThreadProcessId fails — i.e. the target HWND died; any IAccessible call raising a COMException with OOM HRESULT, converted before the critical-exception check (OOM would otherwise be treated as critical).","commonSituations":"Treeview controls being destroyed/recreated while UIA enumerates their proxy; target window handle invalidated between discovery and call; memory pressure in the target process surfacing as OOM HRESULTs during cross-process MSAA calls.","solutions":["Treat this as ElementNotAvailableException on the caller side: re-find the element and retry","Detect and wait for target window recreation (e.g. re-find by WindowPattern / wait for WindowOpenedEvent) instead of using the stale reference","Verify the target application/HWND is still alive (IsWindow / UIA not-visible check) before operating on proxied elements","Batch reads with CacheRequest to minimize the number of cross-process proxy calls during unstable UI states"],"exampleFix":"// before\nvar item = FindTreeItem();\nitem.Select(); // may throw ElementNotAvailable (OOM proxy) after tree rebuild\n// after\nvar item = WaitForElementByAutomationId(id, timeout: 5000);\nif (item != null) item.Select();","handlingStrategy":"retry","validationCode":"if (!IsWindowStillAlive(element)) return null; // e.g. compare RuntimeId / use WindowPattern\nbool IsWindowStillAlive(AutomationElement e) {\n    try { return !e.Current.IsOffscreen || e.Current.BoundingRectangle != Rect.Empty; }\n    catch (ElementNotAvailableException) { return false; }\n}","typeGuard":"static bool TryGet<T>(Func<T> f, out T value) {\n    try { value = f(); return true; }\n    catch (ElementNotAvailableException) { value = default; return false; }\n}","tryCatchPattern":"for (int attempt = 0; attempt < 3; attempt++) {\n    try { DoWork(element); break; }\n    catch (ElementNotAvailableException ex)\n        when (ex.InnerException is COMException ce && ce.HResult == unchecked((int)0x8007000E)) {\n        element = FindElementAgain(); // OOM proxy => HWND likely gone; re-find\n    }\n}","preventionTips":["Wait for window recreation events before re-driving treeview-style controls","Avoid enumerating trees while the target window is being rebuilt","Use CacheRequest to reduce proxy round-trips","Check target process/HWND liveness before calls"],"tags":["uiautomation","msaa","oleacc-proxy","out-of-memory","stale-hwnd"],"backgroundTag":"stale-ui-automation-element","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}