{"record":{"id":"3fd9fbeb3ea319d5","repo":"dotnet/efcore","slug":"required-json-property-property-cannot-contain","errorCode":null,"errorMessage":"Required JSON property '{property}' cannot contain null.","messagePattern":"Required JSON property '(.+?)' cannot contain null\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Query/Internal/RelationalJsonUtilities.cs","lineNumber":99,"sourceCode":"                return;\n            }\n\n            writer.WriteStartObject();\n\n            foreach (var property in complexType.GetProperties())\n            {\n                var jsonPropertyName = property.GetJsonPropertyName();\n                Check.DebugAssert(jsonPropertyName is not null);\n                writer.WritePropertyName(jsonPropertyName);\n\n                var jsonValueReaderWriter = property.GetJsonValueReaderWriter() ?? property.GetTypeMapping().JsonValueReaderWriter;\n\n                var propertyValue = property.GetGetter().GetClrValue(objectValue);\n                if (propertyValue is null && jsonValueReaderWriter?.HandlesNullWrites != true)\n                {\n                    if (!property.IsNullable)\n                    {\n                        throw new InvalidOperationException(RelationalStrings.NullValueInRequiredJsonProperty(property.Name));\n                    }\n\n                    writer.WriteNullValue();\n                }\n                else\n                {\n                    Check.DebugAssert(jsonValueReaderWriter is not null, \"Missing JsonValueReaderWriter on JSON property\");\n                    jsonValueReaderWriter.ToJson(writer, propertyValue);\n                }\n            }\n\n            foreach (var complexProperty in complexType.GetComplexProperties())\n            {\n                var jsonPropertyName = complexProperty.GetJsonPropertyName();\n                Check.DebugAssert(jsonPropertyName is not null);\n                writer.WritePropertyName(jsonPropertyName);\n\n                var propertyValue = complexProperty.GetGetter().GetClrValue(objectValue);","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Relational/Query/Internal/RelationalJsonUtilities.cs#L81-L117","documentation":"Thrown during JSON serialization of an entity mapped to JSON columns when a non-nullable scalar property has a null CLR value and the JsonValueReaderWriter does not handle null writes. This is a data integrity violation: a required (non-nullable) property was set to null at runtime, which EF refuses to silently serialize into JSON.","triggerScenarios":"An entity type is mapped to JSON (ToJson mapping) with a non-nullable property (e.g., int, non-nullable string). At save time, the property's CLR value is null — possible via reflection, uninitialized auto-properties, or default value semantics — triggering the throw inside WriteJson when generating the JSON payload.","commonSituations":"Using [Required] or IsRequired() on a JSON-mapped entity's property but the object instance has that property as null (e.g., partial data from an API payload). Mapping a value type (non-nullable int) but the entity was constructed with Activator.CreateInstance and the getter returns null via a backing field issue. Setting a property to null via reflection or JSON deserialization that bypasses nullability checks.","solutions":["Ensure the property has a non-null value before calling SaveChanges — validate the entity in code.","If the property should allow null, configure it as nullable: IsRequired(false), make the CLR type nullable (int?), or remove [Required].","Add a validator (e.g., in OnSavingChanges or a data annotation validator) that checks JSON-mapped entities for null required properties before save.","If the value comes from external input, reject or default the null at the API boundary."],"exampleFix":"// before\nmodelBuilder.Entity<Order>().OwnsOne(o => o.Address, a =>\n{\n    a.ToJson(\"address\");\n    a.Property(x => x.ZipCode).IsRequired(); // non-nullable string\n});\n// Address.ZipCode is null at save time → throws\n\n// after\nmodelBuilder.Entity<Order>().OwnsOne(o => o.Address, a =>\n{\n    a.ToJson(\"address\");\n    a.Property(x => x.ZipCode).IsRequired(false); // allow null\n});","handlingStrategy":"validation","validationCode":"// Validate JSON-mapped entities before SaveChanges\nforeach (var entry in context.ChangeTracker.Entries())\n{\n    var entityType = entry.Metadata;\n    foreach (var property in entityType.GetProperties())\n    {\n        if (!property.IsNullable && property.IsJsonMapped())\n        {\n            var value = entry.CurrentValues[property];\n            if (value is null)\n                throw new InvalidOperationException(\n                    $\"Required JSON property {property.Name} on {entityType.DisplayName()} is null before save.\");\n        }\n    }\n}","typeGuard":"static bool IsJsonMappedAndRequired(IProperty property)\n    => !property.IsNullable\n       && property.DeclaringType.IsMappedToJson();","tryCatchPattern":"try\n{\n    await context.SaveChangesAsync();\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Required JSON property\") && ex.Message.Contains(\"cannot contain null\"))\n{\n    logger.LogError(ex, \"A required JSON property was null — validate entity data before saving\");\n    throw;\n}","preventionTips":["Add null checks or data annotations validation before SaveChanges for JSON-mapped entities.","Use nullable reference types (NRTs) to catch null assignments at compile time where possible.","For value types mapped to JSON, ensure they are never left at default(null) via constructors or factory methods.","Write unit tests that verify all required JSON properties are non-null on seed data."],"tags":["json-mapping","required-property","null-value","save-changes"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}