{"record":{"id":"dcd2bea46ec7eb49","repo":"MonoGame/MonoGame","slug":"invalid-type-has-been-provided-for-genericcollecti","errorCode":null,"errorMessage":"Invalid type has been provided for GenericCollectionHelper: {type}","messagePattern":"Invalid type has been provided for GenericCollectionHelper: (.+?)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"MonoGame.Framework.Content.Pipeline/Serialization/Intermediate/GenericCollectionHelper.cs","lineNumber":41,"sourceCode":"        {\n            var interfaces = type.FindInterfaces((t, _) =>\n            {\n                if (t.IsGenericType)\n                    return t.GetGenericTypeDefinition() == typeof(ICollection<>);\n                return false;\n            }, null);\n\n            return (interfaces.Length == 1) ? interfaces[0] : null;\n        }\n\n        private readonly ContentTypeSerializer _contentSerializer;\n        private readonly PropertyInfo _countProperty;\n        private readonly MethodInfo _addMethod;\n\n        public GenericCollectionHelper(IntermediateSerializer serializer, Type type)\n        {\n            var collectionElementType = GetCollectionElementType(type, false) ??\n                throw new ArgumentException($\"Invalid type has been provided for GenericCollectionHelper: {type}\", nameof(type));\n            _contentSerializer = serializer.GetTypeSerializer(collectionElementType);\n\n            var collectionType = typeof(ICollection<>).MakeGenericType(collectionElementType);\n            _countProperty = collectionType.GetProperty(\"Count\")!;\n            _addMethod = collectionType.GetMethod(\"Add\", [collectionElementType])!;\n        }\n\n        public bool ObjectIsEmpty(object? list)\n        {\n            if (list == null)\n                return true;\n\n            if (_countProperty.GetValue(list, null) is not int listCount)\n                return true;\n\n            return listCount == 0;\n        }\n","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/MonoGame/MonoGame/blob/1d71bbd0ff4071a03caa583aa3bc56b85924a819/MonoGame.Framework.Content.Pipeline/Serialization/Intermediate/GenericCollectionHelper.cs#L23-L59","documentation":"GenericCollectionHelper expects a type implementing exactly one ICollection<T> so it can resolve the element type, the Count property, and the Add method. GetCollectionElementType returns null when the type implements zero or more than one ICollection<> interface, and the constructor treats that as a programmer error (ArgumentException), not a content error.","triggerScenarios":"The reflective serializer or GetCollectionHelper is handed a type that either (a) implements no generic ICollection<T>, or (b) implements two or more distinct ICollection<T> (e.g. `class Bag : ICollection<int>, ICollection<string>`). FindCollectionInterface returns null when interfaces.Length != 1.","commonSituations":"Authoring a custom collection type meant to be serialized that doesn't implement ICollection<T>, or that ambiguously implements several. Usually a design-time bug in a pipeline extension type, surfaced the first time that type is serialized.","solutions":["Make the collection type implement exactly one ICollection<T> for the element type you want serialized.","If multiple element types are involved, split into separate collection classes or wrap the desired element type.","If you do not want generic-collection serialization semantics, decorate members with [ContentSerializerIgnore] or provide a custom ContentTypeSerializer."],"exampleFix":"// before\npublic class MixedBag : ICollection<int>, ICollection<string> { ... }\n\n// after\npublic class IntBag : ICollection<int> { ... }","handlingStrategy":"type-guard","validationCode":"// Verify a type is a valid single-element generic collection before exposing it to the serializer\nstatic bool IsValidSingleElementCollection(Type t)\n{\n    var ifaces = t.FindInterfaces((tp, _) =>\n        tp.IsGenericType && tp.GetGenericTypeDefinition() == typeof(ICollection<>), null);\n    return ifaces.Length == 1;\n}","typeGuard":"static bool IsSerializableCollection(Type t) =>\n    t.FindInterfaces((tp, _) =>\n        tp.IsGenericType && tp.GetGenericTypeDefinition() == typeof(ICollection<>), null).Length == 1;","tryCatchPattern":"try { serializer.GetCollectionHelper(type); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"GenericCollectionHelper\"))\n{\n    // redesign the type to implement exactly one ICollection<T>\n}","preventionTips":["Implement exactly one ICollection<T> on custom serializable collections.","Unit-test every new collection type through Serialize/Deserialize round-trip.","Avoid multi-element 'bag' types in the serializable model."],"tags":["csharp","monogame","content-pipeline","serialization","collections"],"backgroundTag":null,"analyzedSha":"1d71bbd0ff4071a03caa583aa3bc56b85924a819","analyzedAt":"2026-08-13T17:10:33.625Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}