{"record":{"id":"cf21c32010065343","repo":"dotnet/wpf","slug":"sr-generator-inconsistent","errorCode":null,"errorMessage":"SR.Generator_Inconsistent","messagePattern":"SR\\.Generator_Inconsistent","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"critical","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ItemContainerGenerator.cs","lineNumber":1101,"sourceCode":"                sb.AppendLine();\n\n                sb.AppendLine(SR.Generator_Readme5);                          // The most common causes...\n                sb.AppendLine();\n\n                sb.Append    (SR.Generator_Readme6); sb.Append(\"  \");         // Stack trace describes detection...\n                sb.Append    (SR.Format(SR.Generator_Readme7,                            // To get better detection...\n                                \"PresentationTraceSources.TraceLevel\", \"High\"));\n                sb.Append    (\"  \");\n                sb.AppendLine(SR.Format(SR.Generator_Readme8,                            // One way to do this ...\n                                \"System.Diagnostics.PresentationTraceSources.SetTraceLevel(myItemsControl.ItemContainerGenerator, System.Diagnostics.PresentationTraceLevel.High)\"));\n                sb.AppendLine(SR.Generator_Readme9);                          // This slows down the app.\n\n                // use an inner exception to hold the details.  There's a lot of\n                // information, but it's only interesting to a developer.\n                Exception exception = new Exception(sb.ToString());\n\n                // throw the exception\n                throw new InvalidOperationException(SR.Generator_Inconsistent, exception);\n            }\n        }\n\n        private void FormatCollectionChangedSource(int level, object source, bool? isLikely, List<string> sources)\n        {\n            Type sourceType = source.GetType();\n\n            if (!isLikely.HasValue)\n            {\n                // if the type doesn't come from WPF or DevDiv (e.g. ObservableCollection<T>),\n                // mark it as \"more likely to be at fault\".   I'm not saying we're always right,\n                // just that 3rd parties are more likely to be wrong than we are.\n                isLikely = true;\n\n                const string PublicKeyToken = \"PublicKeyToken=\";\n                string aqn = sourceType.AssemblyQualifiedName;\n                int index = aqn.LastIndexOf(PublicKeyToken);\n                if (index >= 0)","sourceCodeStart":1083,"sourceCodeEnd":1119,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ItemContainerGenerator.cs#L1083-L1119","documentation":"ItemContainerGenerator periodically validates that its internal item map is consistent with the Items collection (VerifyItemMapAndSource). When a mismatch is detected it builds a detailed diagnostic string, wraps it in an inner Exception, and throws InvalidOperationException SR.Generator_Inconsistent to report a broken generator state.","triggerScenarios":"The Items collection was mutated in ways the generator could not track — e.g. raising CollectionChanged events that do not match the actual collection contents, direct mutation of ItemsInternal without notifications, or custom IList implementations raising inconsistent Add/Remove events.","commonSituations":"Custom collection classes with buggy INotifyCollectionChanged implementations; modifying ItemsSource collection from background threads; re-entrancy during collection change notifications.","solutions":["Fix the source collection so its CollectionChanged notifications exactly match its contents (each Add/Remove reflects real items).","Implement INotifyCollectionChanged correctly on custom collections, or wrap with ObservableCollection.","Never mutate the Items collection from multiple threads or re-entrantly while CollectionChanged handlers run."],"exampleFix":"// before\nclass BuggyCollection : List<object>, INotifyCollectionChanged { /* raises events inconsistently */ }\n\n// after\nclass FixedCollection : ObservableCollection<object> { } // notifications always match contents","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { /* bind / refresh ItemsSource */ }\ncatch (InvalidOperationException ex) when (ex.InnerException != null && ex.Message.Contains(\"inconsistent\"))\n{\n    // inspect ex.InnerException for the detailed map dump, then force refresh\n    itemsControl.Items.Refresh();\n}","preventionTips":["Implement INotifyCollectionChanged correctly on custom collections; test with the WPF generator.","Mutate collections only on the UI thread.","Never raise CollectionChanged handlers that mutate the same collection re-entrantly."],"tags":["wpf","itemcontainergenerator","invariant","collection-changed"],"backgroundTag":"internal-invariant-violation","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"}