{"record":{"id":"86aa8c3afe190c09","repo":"dotnet/wpf","slug":"element-is-not-enabled-windowsbutton","errorCode":null,"errorMessage":"Element is not enabled.","messagePattern":"Element is not enabled\\.","errorType":"exception","errorClass":"ElementNotEnabledException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/WindowsButton.cs","lineNumber":463,"sourceCode":"        };\n\n        #endregion\n\n        // ------------------------------------------------------\n        //\n        // Private Methods\n        //\n        // ------------------------------------------------------\n\n        #region Private Methods\n\n        private void Invoke()\n        {\n            // Check that button can be clicked\n            // This state could change anytime\n            if (!SafeNativeMethods.IsWindowEnabled(_hwnd))\n            {\n                throw new ElementNotEnabledException();\n            }\n\n            // Moved this outside the if block because it's needed for WinForms, which uses _acc.DoDefaultAction()\n            if (!IsShowAllProgramsButton())\n            {\n                // SetFocus is needed here to workaround a bug\n                Misc.SetFocus(_hwnd);\n            }\n\n            if (_acc == null)\n            {\n                switch (_style)\n                {\n                    case NativeMethods.BS_PUSHBUTTON:\n                    case NativeMethods.BS_DEFPUSHBUTTON:\n                    case NativeMethods.BS_PUSHBOX:\n                    case NativeMethods.BS_OWNERDRAW:\n                    case NativeMethods.BS_USERBUTTON:","sourceCodeStart":445,"sourceCodeEnd":481,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/WindowsButton.cs#L445-L481","documentation":"ElementNotEnabledException ('Element is not enabled.') is thrown by the WindowsButton proxy's Invoke() when SafeNativeMethods.IsWindowEnabled(_hwnd) reports the underlying Win32 window is disabled. The button's enabled state can change at any moment between the check and the click, which the code explicitly notes; the UIA contract requires invoking a disabled element to fail with this exception. It is a standard UIA provider-side state guard, not a defect.","triggerScenarios":"Calling InvokePattern.Invoke() (or the internal Invoke path used by SelectionItem special cases) on a WindowsButton whose hwnd is disabled (EnableWindow(false), control.Enabled=false in WinForms, or a modal owner blocking the button).","commonSituations":"Test automation clicking buttons during a modal operation (busy cursor, progress dialog) when the app disabled its UI; automation racing a validation flow that disables the button until input is complete; stale references after the app re-enabled/disabled controls.","solutions":["Check IsEnabled on the AutomationElement (or wait for the enabled state) before calling Invoke, e.g. poll until element.Current.IsEnabled.","Retry the Invoke after a short delay if the button is expected to become enabled, since the state can change anytime.","Update the UI state the button depends on (fill required fields, close the modal) so the app enables the button.","Catch ElementNotEnabledException around Invoke and treat it as button-currently-disabled in the automation flow."],"exampleFix":"// before\nvar invoke = button.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;\ninvoke.Invoke();\n// after\nvar invoke = button.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;\nvar deadline = DateTime.UtcNow.AddSeconds(5);\nwhile (!button.Current.IsEnabled && DateTime.UtcNow < deadline)\n    Thread.Sleep(200);\nif (button.Current.IsEnabled)\n    invoke.Invoke();","handlingStrategy":"retry","validationCode":"// C# (UIA client)\nbool enabled = element.Current.IsEnabled;\n// invoke only when enabled; otherwise wait or update app state first","typeGuard":null,"tryCatchPattern":"try\n{\n    var inv = element.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;\n    inv.Invoke();\n}\ncatch (ElementNotEnabledException)\n{\n    // button disabled; wait for it to become enabled or fail the step\n}","preventionTips":["Poll element.Current.IsEnabled with a timeout before Invoke.","Ensure the app state that gates the button (validation, modal) is satisfied before automating.","Retry Invoke with backoff because the enabled state can change anytime.","Catch ElementNotEnabledException at the interaction layer so a transient disable does not abort the whole run."],"tags":["uiautomation","element-not-enabled","invoke-pattern","winforms"],"backgroundTag":"element-not-enabled","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"}