{"record":{"id":"37a04e3853720c81","repo":"JamesNK/Newtonsoft.Json","slug":"type-0-is-not-a-collection","errorCode":null,"errorMessage":"Type {0} is not a collection.","messagePattern":"Type (.+?) is not a collection\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs","lineNumber":422,"sourceCode":"        /// Gets the type of the typed collection's items.\n        /// </summary>\n        /// <param name=\"type\">The type.</param>\n        /// <returns>The type of the typed collection's items.</returns>\n        public static Type? GetCollectionItemType(\n            [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]\n            Type type)\n        {\n            ValidationUtils.ArgumentNotNull(type, nameof(type));\n\n            if (type.IsArray)\n            {\n                return type.GetElementType();\n            }\n            if (ImplementsGenericDefinition(type, typeof(IEnumerable<>), out Type? genericListType))\n            {\n                if (genericListType!.IsGenericTypeDefinition())\n                {\n                    throw new Exception(\"Type {0} is not a collection.\".FormatWith(CultureInfo.InvariantCulture, type));\n                }\n\n                return genericListType!.GetGenericArguments()[0];\n            }\n            if (typeof(IEnumerable).IsAssignableFrom(type))\n            {\n                return null;\n            }\n\n            throw new Exception(\"Type {0} is not a collection.\".FormatWith(CultureInfo.InvariantCulture, type));\n        }\n\n        public static void GetDictionaryKeyValueTypes(\n            [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]\n            Type dictionaryType,\n            out Type? keyType,\n            out Type? valueType)\n        {","sourceCodeStart":404,"sourceCodeEnd":440,"githubUrl":"https://github.com/JamesNK/Newtonsoft.Json/blob/4f73e74372445108d2c1bda37b36e6f5e43402e0/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs#L404-L440","documentation":"Thrown by ReflectionUtils.GetCollectionItemType when a type implements IEnumerable<> but the resolved implementing generic type is itself a generic type definition (still open / unbound). This is an edge case where the element type could not be resolved to a concrete type. The collection lookup succeeded structurally but the type argument remains an open T.","triggerScenarios":"A type whose IEnumerable<> implementation is open (unresolved T) — abstract generic collection bases, or dynamically constructed open generic types reaching GetCollectionItemType. Often seen with reflection-emitted open generic types or misused TypeNameHandling producing open generics.","commonSituations":"Custom generic base classes used as collection types, open generic types leaking into the collection item-type resolution path, or deserializing with TypeNameHandling that resolves to an unbound generic.","solutions":["Serialize/deserialize a closed generic instance (List<int>) rather than the open generic type definition.","Provide a custom JsonConverter that knows the concrete element type.","Ensure any TypeNameHandling-supplied type name resolves to a closed generic."],"exampleFix":"// before\nType t = typeof(List<>); // open generic\nvar itemType = ReflectionUtils.GetCollectionItemType(t);\n\n// after\nType t = typeof(List<int>); // closed generic\nvar itemType = ReflectionUtils.GetCollectionItemType(t);","handlingStrategy":"validation","validationCode":"if (t.IsGenericType && t.ContainsGenericParameters)\n    throw new ArgumentException(\"Pass a closed generic collection, not an open definition.\");","typeGuard":"static bool IsClosedGenericCollection(Type t) => t.IsGenericType && !t.ContainsGenericParameters && typeof(IEnumerable).IsAssignableFrom(t);","tryCatchPattern":null,"preventionTips":["Never pass open generic type definitions to collection-handling code; use closed instances.","Guard types with ContainsGenericParameters before collection resolution.","Provide a custom converter for open-generic base collection types."],"tags":["reflection","collection","generics","open-generic"],"analyzedSha":"4f73e74372445108d2c1bda37b36e6f5e43402e0","analyzedAt":"2026-08-07T06:10:08.596Z","schemaVersion":2},"datasetVersion":"2026-08-07T07:17:06.508Z"}