{"record":{"id":"afd65db968c25d12","repo":"dotnet/efcore","slug":"complex-property-complexproperty-cannot-use-h","errorCode":null,"errorMessage":"Complex property '{complexProperty}' cannot use 'HasJsonPropertyName()' because it is not contained within a JSON-mapped type. Use 'ToJson()' to map the complex property to a JSON column, or ensure it is contained within a type that is mapped to JSON.","messagePattern":"Complex property '(.+?)' cannot use 'HasJsonPropertyName\\(\\)' because it is not contained within a JSON-mapped type\\. Use 'ToJson\\(\\)' to map the complex property to a JSON column, or ensure it is contained within a type that is mapped to JSON\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs","lineNumber":295,"sourceCode":"        {\n            throw new InvalidOperationException(\n                RelationalStrings.ComplexPropertyOptionalTableSharing(complexProperty.ComplexType.DisplayName(), complexProperty.Name));\n        }\n\n        if (complexProperty.GetJsonPropertyName() != null)\n        {\n            if (complexProperty.ComplexType.FindAnnotation(RelationalAnnotationNames.ContainerColumnName)?.Value is string columnName)\n            {\n                throw new InvalidOperationException(\n                    RelationalStrings.ComplexPropertyBothJsonColumnAndJsonPropertyName(\n                        $\"{complexProperty.DeclaringType.DisplayName()}.{complexProperty.Name}\",\n                        columnName,\n                        complexProperty.GetJsonPropertyName()));\n            }\n\n            if (!complexProperty.DeclaringType.IsMappedToJson())\n            {\n                throw new InvalidOperationException(\n                    RelationalStrings.ComplexPropertyJsonPropertyNameWithoutJsonMapping(\n                        $\"{complexProperty.DeclaringType.DisplayName()}.{complexProperty.Name}\"));\n            }\n        }\n\n        if (complexProperty.ComplexType.IsMappedToJson())\n        {\n            if (!complexProperty.DeclaringType.IsMappedToJson()\n                && complexProperty.DeclaringType is IComplexType)\n            {\n                // Issue #36558\n                throw new InvalidOperationException(\n                    RelationalStrings.NestedComplexPropertyJsonWithTableSharing(\n                        $\"{complexProperty.DeclaringType.DisplayName()}.{complexProperty.Name}\",\n                        complexProperty.DeclaringType.DisplayName()));\n            }\n\n            ValidateJsonProperties(complexProperty.ComplexType);","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs#L277-L313","documentation":"ValidatePropertyMapping (RelationalModelValidator.cs:293-298) throws when a complex property has a HasJsonPropertyName configured but its declaring type is NOT mapped to JSON. HasJsonPropertyName only makes sense for a property nested inside a JSON document; without a containing JSON column there is nowhere for the JSON key to live, so the configuration is rejected.","triggerScenarios":"Calling HasJsonPropertyName(\"key\") on a complex property whose owning entity/complex type is mapped to a regular table (not via ToJson). Thrown at model validation.","commonSituations":"Configuring JSON property names on complex types that are table-mapped; applying a HasJsonPropertyName convention to non-JSON entities; partial JSON migration where the root ToJson() was forgotten.","solutions":["Map the containing type to JSON: add ToJson() on the root complex property/entity so the HasJsonPropertyName has a home.","If the property should remain table-mapped (flattened to columns), remove HasJsonPropertyName() and use HasColumnName() instead.","Ensure the entire chain from the entity root down is JSON-mapped before setting JSON property names on nested members."],"exampleFix":"// before - HasJsonPropertyName with no JSON container\nmodelBuilder.Entity<Customer>().OwnsOne(c => c.Profile, p =>\n{\n    p.HasJsonPropertyName(\"profile\"); // Customer not mapped to JSON -> throws\n});\n\n// after - either map container to JSON\nmodelBuilder.Entity<Customer>().OwnsOne(c => c.Details, d =>\n{\n    d.ToJson(\"DetailsJson\");\n    d.OwnsOne(c => c.Profile, p => p.HasJsonPropertyName(\"profile\"));\n});\n// OR drop HasJsonPropertyName and use column mapping for table-shared complex type","handlingStrategy":"validation","validationCode":"foreach (var et in context.Model.GetEntityTypes())\n{\n    foreach (var cp in et.GetComplexProperties())\n    {\n        if (cp.GetJsonPropertyName() != null && !cp.DeclaringType.IsMappedToJson())\n        {\n            // will throw - map the containing type to JSON or use HasColumnName instead.\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only set HasJsonPropertyName when the containing type is JSON-mapped.","Use HasColumnName() for table-flattened complex properties.","Verify the whole JSON chain is rooted before setting nested JSON names."],"tags":["json-mapping","complex-type","model-validation"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T02:17:10.218Z"}