{"record":{"id":"c5838294c0893be7","repo":"JamesNK/Newtonsoft.Json","slug":"type-0-is-not-a-dictionary","errorCode":null,"errorMessage":"Type {0} is not a dictionary.","messagePattern":"Type (.+?) is not a dictionary\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs","lineNumber":447,"sourceCode":"                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        {\n            ValidationUtils.ArgumentNotNull(dictionaryType, nameof(dictionaryType));\n\n            if (ImplementsGenericDefinition(dictionaryType, typeof(IDictionary<,>), out Type? genericDictionaryType))\n            {\n                if (genericDictionaryType!.IsGenericTypeDefinition())\n                {\n                    throw new Exception(\"Type {0} is not a dictionary.\".FormatWith(CultureInfo.InvariantCulture, dictionaryType));\n                }\n\n                Type[] dictionaryGenericArguments = genericDictionaryType!.GetGenericArguments();\n\n                keyType = dictionaryGenericArguments[0];\n                valueType = dictionaryGenericArguments[1];\n                return;\n            }\n            if (typeof(IDictionary).IsAssignableFrom(dictionaryType))\n            {\n                keyType = null;\n                valueType = null;\n                return;\n            }\n\n            throw new Exception(\"Type {0} is not a dictionary.\".FormatWith(CultureInfo.InvariantCulture, dictionaryType));\n        }\n","sourceCodeStart":429,"sourceCodeEnd":465,"githubUrl":"https://github.com/JamesNK/Newtonsoft.Json/blob/4f73e74372445108d2c1bda37b36e6f5e43402e0/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs#L429-L465","documentation":"Thrown by ReflectionUtils.GetDictionaryKeyValueTypes when a type implements IDictionary<,> but the resolved implementing generic type is a generic type definition (open / unbound). The key/value types could not be resolved to concrete types, analogous to error 269 for collections.","triggerScenarios":"A type whose IDictionary<,> implementation is still open — abstract generic dictionary bases, or dynamically constructed open generic types reaching this path.","commonSituations":"Custom generic dictionary base classes used directly, open generic types leaking into dictionary resolution, or TypeNameHandling resolving to an unbound generic dictionary.","solutions":["Use a closed generic dictionary type (Dictionary<string, int>) rather than an open one.","Provide a custom JsonConverter that supplies concrete key/value types.","Ensure any type-name-resolved dictionary type is closed."],"exampleFix":"// before\nType t = typeof(Dictionary<,>);\nReflectionUtils.GetDictionaryKeyValueTypes(t, out var k, out var v);\n\n// after\nType t = typeof(Dictionary<string, int>);\nReflectionUtils.GetDictionaryKeyValueTypes(t, out var k, out var v);","handlingStrategy":"validation","validationCode":"if (t.IsGenericType && t.ContainsGenericParameters)\n    throw new ArgumentException(\"Pass a closed generic dictionary, not an open definition.\");","typeGuard":"static bool IsClosedGenericDictionary(Type t) => t.IsGenericType && !t.ContainsGenericParameters && typeof(IDictionary).IsAssignableFrom(t);","tryCatchPattern":null,"preventionTips":["Never pass open generic dictionary definitions; use closed instances.","Guard with ContainsGenericParameters before dictionary resolution.","Provide a custom converter for open-generic base dictionary types."],"tags":["reflection","dictionary","generics","open-generic"],"analyzedSha":"4f73e74372445108d2c1bda37b36e6f5e43402e0","analyzedAt":"2026-08-07T06:10:08.596Z","schemaVersion":2},"datasetVersion":"2026-08-07T07:17:06.508Z"}