{"record":{"id":"7be533a5c27882f3","repo":"dotnet/wpf","slug":"sr-operationcannotbeperformed-windowslistviewgrouphelper","errorCode":null,"errorMessage":"SR.OperationCannotBePerformed","messagePattern":"SR\\.OperationCannotBePerformed","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/WindowsListViewGroupHelper.cs","lineNumber":61,"sourceCode":"        internal bool Contains(IntPtr hwnd)\n        {\n            return _groupManagers.ContainsKey(hwnd);\n        }\n\n        internal GroupManager this[IntPtr hwnd]\n        {\n            get\n            {\n                if (!WindowsListView.IsGroupViewEnabled(hwnd))\n                {\n                    // Group was disabled but we did not get the needed event\n                    // since for some things events are not being sent\n                    // (e.g: Going from some LV modes to - List mode, List mode does not have Groups)\n\n                    // Microsoft - We may want to consider raising the event here\n                    // The M7 work on checking if LE is valid however is the better way of going\n                    // WindowsListView.RemoveGroupAndRaiseLogicalChangedEvent(_hwnd);\n                    throw new InvalidOperationException(SR.OperationCannotBePerformed);\n                }\n\n                // The group may have been discarded by the reorder winevent.\n                EnsureCreation (hwnd);\n\n                GroupManager manager = _groupManagers[hwnd] as GroupManager;\n                if (manager == null)\n                {\n                    // E.G. Going from the List mode to the something that has Group will cause this\n\n                    // Microsoft- We may want to consider raising the event here\n                    // The M7 work on checking if LE is valid however is the better way of going\n                    // WindowsListView.RaiseLogicalChangedEvent(hwnd);\n                    throw new InvalidOperationException(SR.OperationCannotBePerformed);\n                }\n                return manager;\n            }\n        }","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/WindowsListViewGroupHelper.cs#L43-L79","documentation":"GroupManagerCollection.GetManager (public) throws InvalidOperationException(SR.OperationCannotBePerformed) when a list-view HWND that is being queried has no group manager registered even though groups should exist - typically because the control transitioned out of a grouped mode (e.g. switching to List mode, which has no groups) and WinEvents for the removal were not delivered. The provider cannot hand back a valid manager and aborts with this sentinel exception. Comments again note the intended fix (RemoveGroupAndRaiseLogicalChangedEvent) was deferred.","triggerScenarios":"Calling GetManager(hwnd) for a ListView whose view mode changed from a grouped mode (e.g. Details/Tile with groups) to List mode; the group manager was removed on the corresponding WinEvent but a lookup still arrives, or vice versa the reorder WinEvent was missed.","commonSituations":"UIA clients holding a cached ListView element while the user (or app code) changes ListView.View at runtime; grouped list views in Explorer-like UIs being toggled; test harnesses switching view modes mid-automation run.","solutions":["Re-fetch the list element after the view-mode change so the provider re-registers group managers, then retry.","Catch InvalidOperationException around UIA pattern calls and treat it as a signal the control's structure changed; invalidate cached children.","Delay automation calls until after the ListView.View change completes (wait for the structure-changed event instead of polling immediately).","If you own the app, switch view modes when no UIA clients are subscribed, or explicitly send a structure-changed notification after the change."],"exampleFix":"// before\nvar item = cachedListElement.FindFirst(TreeScope.Children, nameCond);\n\n// after\nAutomationElement item;\ntry { item = cachedListElement.FindFirst(TreeScope.Children, nameCond); }\ncatch (InvalidOperationException)\n{\n    cachedListElement = ReFindList();   // refresh after a View change\n    item = cachedListElement.FindFirst(TreeScope.Children, nameCond);\n}","handlingStrategy":"try-catch","validationCode":"if (list.FindAll(TreeScope.Children, groupCond).Count == 0) return null; // no groups to query","typeGuard":"bool HasGroups(AutomationElement list) => list.FindAll(TreeScope.Children, groupCond).Count > 0;","tryCatchPattern":"try { return GetManagerDependentCall(list); }\ncatch (InvalidOperationException) { list = RefindElement(hwnd); return GetManagerDependentCall(list); }","preventionTips":["Wait for StructureChanged events after ListView.View mode switches before querying groups","Do not cache group child elements across view-mode changes","Batch view-mode changes in your app and raise one structure-changed notification","Re-query the list from its runtime ID after any grouped/non-grouped transition"],"tags":["uiautomation","wpf","listview","groups","invalidoperationexception"],"backgroundTag":"unsupported-operation","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"}