{"record":{"id":"4908460cf29432c3","repo":"JamesNK/Newtonsoft.Json","slug":"cannot-set-value-onto-extension-data-member-0","errorCode":null,"errorMessage":"Cannot set value onto extension data member '{0}'. The extension data collection is null and it cannot be set.","messagePattern":"Cannot set value onto extension data member '(.+?)'\\. The extension data collection is null and it cannot be set\\.","errorType":"exception","errorClass":"JsonSerializationException","httpStatus":null,"severity":"error","filePath":"Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs","lineNumber":546,"sourceCode":"                Func<object> createExtensionDataDictionary = JsonTypeReflector.ReflectionDelegateFactory.CreateDefaultConstructor<object>(createdType);\n                MethodInfo? setMethod = t.GetProperty(\"Item\", BindingFlags.Public | BindingFlags.Instance, null, valueType, new[] { keyType }, null)?.GetSetMethod();\n                if (setMethod == null)\n                {\n                    // Item is explicitly implemented and non-public\n                    // get from dictionary interface\n                    setMethod = dictionaryType!.GetProperty(\"Item\", BindingFlags.Public | BindingFlags.Instance, null, valueType, new[] { keyType }, null)?.GetSetMethod();\n                }\n\n                MethodCall<object, object?> setExtensionDataDictionaryValue = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(setMethod!);\n\n                ExtensionDataSetter extensionDataSetter = (o, key, value) =>\n                {\n                    object? dictionary = getExtensionDataDictionary(o);\n                    if (dictionary == null)\n                    {\n                        if (setExtensionDataDictionary == null)\n                        {\n                            throw new JsonSerializationException(\"Cannot set value onto extension data member '{0}'. The extension data collection is null and it cannot be set.\".FormatWith(CultureInfo.InvariantCulture, member.Name));\n                        }\n\n                        dictionary = createExtensionDataDictionary();\n                        setExtensionDataDictionary(o, dictionary);\n                    }\n\n                    setExtensionDataDictionaryValue(dictionary, key, value);\n                };\n\n                contract.ExtensionDataSetter = extensionDataSetter;\n            }\n\n            if (extensionDataAttribute.WriteData)\n            {\n                Type enumerableWrapper = typeof(EnumerableDictionaryWrapper<,>).MakeGenericType(keyType, valueType);\n                ConstructorInfo constructors = enumerableWrapper.GetConstructors().First();\n                ObjectConstructor<object> createEnumerableWrapper = JsonTypeReflector.ReflectionDelegateFactory.CreateParameterizedConstructor(constructors);\n","sourceCodeStart":528,"sourceCodeEnd":564,"githubUrl":"https://github.com/JamesNK/Newtonsoft.Json/blob/4f73e74372445108d2c1bda37b36e6f5e43402e0/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs#L528-L564","documentation":"When reading extra JSON properties into an extension-data member, Json.NET reads the member's dictionary at runtime; if it is null and the member cannot be assigned (no setter / not settable, so setExtensionDataDictionary is null), the ExtensionDataSetter throws a JsonSerializationException (line 546). The library cannot create a dictionary and assign it back, so capture fails.","triggerScenarios":"[JsonExtensionData] (with ReadData = true, the default) on a get-only property whose backing dictionary is never initialized, then deserializing JSON that contains properties not mapped to members.","commonSituations":"Auto-property with only a getter and no initializer, or a readonly field left null, used to collect overflow properties during deserialization.","solutions":["Initialize the dictionary at declaration: 'get;' backed by '= new Dictionary<string, JToken>()'.","Give the property a setter so Json.NET can create and assign the dictionary.","Initialize the collection in the type's constructor before deserialization."],"exampleFix":"// before\n[JsonExtensionData]\npublic IDictionary<string, JToken> Extra { get; } // null at runtime -> throws\n\n// after\n[JsonExtensionData]\npublic IDictionary<string, JToken> Extra { get; set; } = new Dictionary<string, JToken>();","handlingStrategy":"validation","validationCode":"foreach (var p in typeof(T).GetProperties().Where(p => p.IsDefined(typeof(JsonExtensionDataAttribute), false)))\n{\n    var attr = (JsonExtensionDataAttribute)Attribute.GetCustomAttribute(p, typeof(JsonExtensionDataAttribute));\n    if (attr.ReadData && p.GetSetMethod(true) == null)\n    {\n        // property has no setter -> must be initialized in a constructor or initializer\n        var ctorInit = typeof(T).GetConstructors().Any(c => /* check field/prop assignment */ false);\n        if (!ctorInit)\n            throw new InvalidOperationException($\"{p.Name} is read-only; initialize it or add a setter.\");\n    }\n}","typeGuard":"static bool ExtensionDataIsSafeForRead(MemberInfo m)\n{\n    var attr = (JsonExtensionDataAttribute)Attribute.GetCustomAttribute(m, typeof(JsonExtensionDataAttribute))!;\n    if (attr == null || !attr.ReadData) return true;\n    var prop = m as PropertyInfo;\n    return prop == null || prop.GetSetMethod(true) != null || /* initialized elsewhere */ false;\n}","tryCatchPattern":"try { JsonConvert.DeserializeObject<T>(json); }\ncatch (JsonSerializationException ex) when (ex.Message.Contains(\"extension data collection is null\"))\n{\n    // initialize the dictionary at declaration or add a setter\n}","preventionTips":["Initialize extension-data collections at declaration: '= new Dictionary<string, JToken>()'.","Give the extension-data property a setter, or set it in a constructor."],"tags":["extension-data","deserialization","null-reference"],"analyzedSha":"4f73e74372445108d2c1bda37b36e6f5e43402e0","analyzedAt":"2026-08-07T06:10:08.596Z","schemaVersion":2},"datasetVersion":"2026-08-07T07:17:06.508Z"}