dotnet/efcore · error · InvalidOperationException
Required JSON property
Error message
Required JSON property '{property}' cannot contain null. What it means
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.
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.
Example fix
// before
modelBuilder.Entity<Order>().OwnsOne(o => o.Address, a =>
{
a.ToJson("address");
a.Property(x => x.ZipCode).IsRequired(); // non-nullable string
});
// Address.ZipCode is null at save time → throws
// after
modelBuilder.Entity<Order>().OwnsOne(o => o.Address, a =>
{
a.ToJson("address");
a.Property(x => x.ZipCode).IsRequired(false); // allow null
}); Defensive patterns
Strategy: validation
Validate before calling
// Validate JSON-mapped entities before SaveChanges
foreach (var entry in context.ChangeTracker.Entries())
{
var entityType = entry.Metadata;
foreach (var property in entityType.GetProperties())
{
if (!property.IsNullable && property.IsJsonMapped())
{
var value = entry.CurrentValues[property];
if (value is null)
throw new InvalidOperationException(
$"Required JSON property {property.Name} on {entityType.DisplayName()} is null before save.");
}
}
} Type guard
static bool IsJsonMappedAndRequired(IProperty property)
=> !property.IsNullable
&& property.DeclaringType.IsMappedToJson(); Try / catch
try
{
await context.SaveChangesAsync();
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Required JSON property") && ex.Message.Contains("cannot contain null"))
{
logger.LogError(ex, "A required JSON property was null — validate entity data before saving");
throw;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- An error occurred while reading a database value. The…
- Both properties ' ' and ' ' on entity type ' ' are mapped…
- Complex property ' ' cannot have both a JSON column name ('…
- Complex property ' ' cannot use 'HasJsonPropertyName()'…
- Complex property ' ' is mapped to JSON but its containing…
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/3fd9fbeb3ea319d5.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Relational/Query/Internal/RelationalJsonUtilities.cs:99
return;
}
writer.WriteStartObject();
foreach (var property in complexType.GetProperties())
{
var jsonPropertyName = property.GetJsonPropertyName();
Check.DebugAssert(jsonPropertyName is not null);
writer.WritePropertyName(jsonPropertyName);
var jsonValueReaderWriter = property.GetJsonValueReaderWriter() ?? property.GetTypeMapping().JsonValueReaderWriter;
var propertyValue = property.GetGetter().GetClrValue(objectValue);
if (propertyValue is null && jsonValueReaderWriter?.HandlesNullWrites != true)
{
if (!property.IsNullable)
{
throw new InvalidOperationException(RelationalStrings.NullValueInRequiredJsonProperty(property.Name));
}
writer.WriteNullValue();
}
else
{
Check.DebugAssert(jsonValueReaderWriter is not null, "Missing JsonValueReaderWriter on JSON property");
jsonValueReaderWriter.ToJson(writer, propertyValue);
}
}
foreach (var complexProperty in complexType.GetComplexProperties())
{
var jsonPropertyName = complexProperty.GetJsonPropertyName();
Check.DebugAssert(jsonPropertyName is not null);
writer.WritePropertyName(jsonPropertyName);
var propertyValue = complexProperty.GetGetter().GetClrValue(objectValue);View on GitHub (pinned to 3a2006ef56)