{"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/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs#L277-L313","documentation":"ValidatePropertyMapping throws ComplexPropertyJsonPropertyNameWithoutJsonMapping when a complex property has HasJsonPropertyName configured but its declaring type is not itself mapped to JSON. HasJsonPropertyName only makes sense inside a containing JSON column; using it on a complex property whose owner is a regular table is meaningless, so the validator blocks it. The message directs the user to ToJson() or to relocate the property inside a JSON-mapped type.","triggerScenarios":"Calling HasJsonPropertyName on a complex property whose DeclaringType.IsMappedToJson() is false — e.g. a top-level entity owns a complex property with HasJsonPropertyName but the entity is mapped to a table, not JSON.","commonSituations":"Misusing HasJsonPropertyName (a JSON-within-JSON API) as a column name override; configuring a complex property as if it were a JSON sub-property without ever marking the owner as JSON; scaffolding tools that emit HasJsonPropertyName unconditionally.","solutions":["If the owner is meant to be JSON, add ToJson() to the appropriate owning entity/complex property.","Otherwise remove HasJsonPropertyName() and use HasColumnName() to control the flattened column name instead.","Move the complex property under a JSON-mapped parent if it should indeed be a JSON sub-property."],"exampleFix":"// before — Customer is a table, Address has a JSON property name\nmodelBuilder.Entity<Customer>()\n    .OwnsOne(c => c.Address, a => a.HasJsonPropertyName(\"addr\")); // throws\n\n// after — use a column name override for flattened mapping\nmodelBuilder.Entity<Customer>()\n    .OwnsOne(c => c.Address, a => a.Property(p => p.City).HasColumnName(\"address_city\"));","handlingStrategy":"validation","validationCode":"if (complexProperty.GetJsonPropertyName() != null\n    && !complexProperty.DeclaringType.IsMappedToJson())\n    throw new InvalidOperationException(\"HasJsonPropertyName requires the declaring type to be JSON-mapped.\");","typeGuard":"static bool HasJsonPropertyNameWithoutJsonParent(IComplexProperty cp)\n    => cp.GetJsonPropertyName() != null && !cp.DeclaringType.IsMappedToJson();","tryCatchPattern":null,"preventionTips":["Only use HasJsonPropertyName inside a JSON-mapped containing type.","Use HasColumnName to override flattened column names on table-mapped complex properties.","Move complex properties under a JSON-mapped parent if they should be JSON sub-properties."],"tags":["complex-type","json-mapping","configuration-conflict","model-validation"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}