{"record":{"id":"bf8b726135d94480","repo":"dotnet/wpf","slug":"elementnotavailableexception-elementutil","errorCode":null,"errorMessage":"ElementNotAvailableException","messagePattern":"ElementNotAvailableException","errorType":"exception","errorClass":"ElementNotAvailableException","httpStatus":null,"severity":"warning","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Automation/ElementUtil.cs","lineNumber":182,"sourceCode":"        // Ensures that an element is enabled; throws exception otherwise\n        internal static void CheckEnabled(Visual visual)\n        {\n            UIElement el = visual as UIElement;\n            \n            if( el != null && ! el.IsEnabled )\n            {\n                throw new ElementNotEnabledException();\n            }\n        }\n\n        internal static object Invoke(AutomationPeer peer, DispatcherOperationCallback work, object arg)\n        {\n            Dispatcher dispatcher = peer.Dispatcher;\n\n            // Null dispatcher likely means the visual is in bad shape!\n            if( dispatcher == null )\n            {\n                throw new ElementNotAvailableException();\n            }\n\n            Exception remoteException = null;\n            bool completed = false;\n\n            object retVal = dispatcher.Invoke(            \n                DispatcherPriority.Send,\n                TimeSpan.FromMinutes(3),\n                (DispatcherOperationCallback) delegate(object unused)\n                {\n                    try\n                    {\n                        return work(arg);\n                    }\n                    catch(Exception e)\n                    {\n                        remoteException = e;\n                        return null;","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Automation/ElementUtil.cs#L164-L200","documentation":"ElementUtil.Invoke marshals an automation peer call onto the peer's dispatcher thread. Before doing so it reads peer.Dispatcher; if the dispatcher is null the visual/HWND backing the peer is already disconnected, so any property or pattern call would be meaningless. The library throws ElementNotAvailableException to tell UIA clients the element has gone away.","triggerScenarios":"Calling any automation peer API (e.g. InvokePattern.Invoke, GetPropertyValue) routed through ElementUtil.Invoke when the peer's Dispatcher is null — typically because the underlying Visual/CoreDisconnected owner has been torn down or detached from the tree before the UIA call arrived.","commonSituations":"UI Automation clients (inspect.exe, screen readers, test frameworks) enumerate elements while the app closes a window or removes a control; a race where the element is destroyed between discovery and the follow-up call; accessing peers of controls on a closing page.","solutions":["Check the element still exists in the live UI tree before automating it (e.g. verify IsOffscreen/Hwnd source is non-null).","Wrap the UIA client call in try/catch for ElementNotAvailableException and treat it as 'element gone', retrying with a fresh element reference.","Re-query the element (FindFirst via the parent) instead of caching stale AutomationElement references across UI updates.","In custom peer code, never hand out peers whose owner is disconnected; override and return null/false where the API allows."],"exampleFix":"// before (client)\nvar valuePattern = (ValuePattern)element.GetCurrentPattern(ValuePattern.Pattern);\nvaluePattern.SetValue(text);\n// after\nif (element.Current.IsEnabled && !element.Current.IsOffscreen)\n{\n    try\n    {\n        var valuePattern = (ValuePattern)element.GetCurrentPattern(ValuePattern.Pattern);\n        valuePattern.SetValue(text);\n    }\n    catch (ElementNotAvailableException)\n    {\n        element = parent.FindFirst(TreeScope.Children, condition); // refresh stale reference\n    }\n}","handlingStrategy":"try-catch","validationCode":"if (element == null) throw new InvalidOperationException(\"element is stale\");\n// re-check freshness before use:\nbool alive = element.Current.IsEnabled || !element.Current.IsOffscreen;","typeGuard":"bool IsElementAlive(AutomationElement e) => e != null && e.GetRuntimeId() != null;","tryCatchPattern":"try\n{\n    var value = element.GetCurrentPropertyValue(AutomationElement.NameProperty);\n}\ncatch (ElementNotAvailableException)\n{\n    element = parent.FindFirst(TreeScope.Children, condition); // refresh and retry\n}","preventionTips":["Never cache AutomationElement references across UI structural changes","Re-query elements from their parent after window/page navigation","Wrap every automation call in ElementNotAvailableException handling in test frameworks","Automate only when the target window is fully loaded and idle"],"tags":["wpf","ui-automation","stale-element","dispatcher"],"backgroundTag":"stale-element-reference","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}