{"record":{"id":"12a0c6cea6035758","repo":"dotnet/wpf","slug":"elementnotavailableexception","errorCode":null,"errorMessage":"ElementNotAvailableException","messagePattern":"ElementNotAvailableException","errorType":"exception","errorClass":"ElementNotAvailableException","httpStatus":null,"severity":"warning","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Automation/ElementProxy.cs","lineNumber":80,"sourceCode":"        // to UIAutomation.\n        //\n        // Interface IRawElementProviderFragmentRoot 'derives' from\n        // IRawElementProviderSimple and IRawElementProviderFragment,\n        // methods from those appear first below.\n        //\n        // Most of the interface methods on this interface need\n        // to get onto the Visual's context before they can access it,\n        // so use Dispatcher.Invoke to call a private method (in the\n        // private methods section of this class) that does the real work.\n\n        // IRawElementProviderSimple methods...\n\n        public object GetPatternProvider ( int pattern )\n        {\n            AutomationPeer peer = Peer;\n            if (peer == null)\n            {\n                throw new ElementNotAvailableException();\n            }\n            return ElementUtil.Invoke(peer, new DispatcherOperationCallback( InContextGetPatternProvider ), pattern);\n        }\n\n        public object GetPropertyValue(int property)\n        {\n            AutomationPeer peer = Peer;\n            if (peer == null)\n            {\n                throw new ElementNotAvailableException();\n            }\n            return ElementUtil.Invoke(peer, new DispatcherOperationCallback(InContextGetPropertyValue), property);\n        }\n\n        public ProviderOptions ProviderOptions\n        {\n            get \n            {","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Automation/ElementProxy.cs#L62-L98","documentation":"ElementProxy.GetPatternProvider is the UI Automation remote provider bridge: it resolves the underlying AutomationPeer and, if the peer is gone (element destroyed or no longer available on the dispatcher), throws ElementNotAvailableException per UIA contract to signal the element is no longer usable.","triggerScenarios":"A UIA client (or WPF's automation infrastructure) queries a pattern on an ElementProxy whose AutomationPeer has been disconnected — typically the corresponding UIElement was removed from the visual tree, its window closed, or the peer was collected before the cross-thread DispatcherOperation ran.","commonSituations":"UIA clients (inspect.exe, screen readers, automated tests) racing with UI teardown; tests asserting properties on controls after the window closed; ItemsControl virtualization discarding containers mid-automation call.","solutions":["Catch ElementNotAvailableException in UIA client code and treat the element as stale — re-query the tree for the current element.","Ensure the automation client re-resolves elements after UI updates instead of caching proxies across layout changes.","In provider code, keep the AutomationPeer alive as long as the proxy may be queried (the element's lifetime, not just the call).","In tests, wait for UI readiness (Dispatcher idle / virtualization complete) before issuing automation calls."],"exampleFix":"// before\nvar value = (string)element.GetCurrentPropertyValue(ValuePattern.ValueProperty);\n// after\ntry\n{\n    var value = (string)element.GetCurrentPropertyValue(ValuePattern.ValueProperty);\n}\ncatch (ElementNotAvailableException)\n{\n    element = tree.Refresh(element); // element went away; re-resolve\n}","handlingStrategy":"try-catch","validationCode":"// client-side: re-resolve element before use\nif (element == null || !element.Current.IsAvailable) // may itself throw; wrap in try\n    element = FindElementAgain();","typeGuard":"bool IsAlive(System.Windows.Automation.AutomationElement el)\n{\n    try { var _ = el.Current.Name; return true; }\n    catch (ElementNotAvailableException) { return false; }\n}","tryCatchPattern":"try\n{\n    var pattern = (ValuePattern)element.GetCurrentPattern(ValuePattern.Pattern);\n}\ncatch (ElementNotAvailableException)\n{\n    element = FindElementAgain(); // stale proxy: re-query the tree\n}","preventionTips":["Never cache AutomationElement references across UI updates; re-resolve after changes.","In tests, wait for dispatcher idle and virtualization before automation calls.","Always treat ElementNotAvailableException as 're-query', not 'retry same element'.","Avoid closing/rebuilding windows while automation clients hold live references."],"tags":["wpf","ui-automation","stale-element","threading"],"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"}