{"record":{"id":"eb1e1dcf010bc2ce","repo":"dotnet/efcore","slug":"executeupdatecannotsetjsonpropertytononjsoncolumn","errorCode":"ExecuteUpdateCannotSetJsonPropertyToNonJsonColumn","errorMessage":"'ExecuteUpdate' cannot currently set a property in a JSON column to a regular, non-JSON column; see https://github.com/dotnet/efcore/issues/36688.","messagePattern":"'ExecuteUpdate' cannot currently set a property in a JSON column to a regular, non-JSON column; see https://github\\.com/dotnet/efcore/issues/36688\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs","lineNumber":391,"sourceCode":"                    var typeMapping = jsonScalar.TypeMapping;\n                    Check.DebugAssert(typeMapping is not null);\n\n                    // We should never see a JsonScalarExpression without a path - that means we're mapping a JSON scalar directly to a relational column.\n                    // This is in theory possible (e.g. map a DateTime to a 'json' column with a single string timestamp representation inside, instead of to\n                    // SQL Server datetime2), but contrived and unsupported.\n                    Check.DebugAssert(jsonScalar.Path.Count > 0);\n\n                    ProcessColumn(jsonColumn, targetProperty);\n\n                    var translatedValue = TranslateScalarSetterValueSelector(source, valueSelector, jsonScalar.Type, typeMapping);\n\n                    // We now have the relational scalar expression for the value; but we need the JSON representation to pass to the provider's JSON modification\n                    // function (e.g. SQL Server JSON_MODIFY()).\n                    // For example, for a DateTime we'd have e.g. a SqlConstantExpression containing a DateTime instance, but we need a string containing\n                    // the JSON-encoded ISO8601 representation.\n                    if (!TrySerializeScalarToJson(jsonScalar, translatedValue, out var jsonValue))\n                    {\n                        throw new InvalidOperationException(\n                            translatedValue is ColumnExpression\n                                ? RelationalStrings.ExecuteUpdateCannotSetJsonPropertyToNonJsonColumn\n                                : RelationalStrings.ExecuteUpdateCannotSetJsonPropertyToArbitraryExpression);\n                    }\n\n                    // We now have a serialized JSON value (number, string or bool) - generate a setter for it.\n                    GenerateJsonPartialUpdateSetterWrapper(jsonScalar, jsonColumn, jsonValue);\n                    continue;\n                }\n\n                case StructuralTypeShaperExpression { ValueBufferExpression: JsonQueryExpression jsonQuery }:\n                    ProcessStructuralJsonSetter(jsonQuery);\n                    continue;\n\n                case CollectionResultExpression { QueryExpression: JsonQueryExpression jsonQuery }:\n                    ProcessStructuralJsonSetter(jsonQuery);\n                    continue;\n","sourceCodeStart":373,"sourceCodeEnd":409,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs#L373-L409","documentation":"When SetProperty targets a scalar property inside a JSON column (JsonScalarExpression, line 371-400), EF must serialize the value to its JSON representation via TrySerializeScalarToJson. If the value is another regular ColumnExpression (a non-JSON column), there is no way to convert a column's runtime value into JSON server-side, so the non-JSON-column branch at line 391-394 throws ExecuteUpdateCannotSetJsonPropertyToNonJsonColumn (tracked by issue #36688).","triggerScenarios":"Assigning a regular relational column to a JSON scalar path: SetProperty(e => e.JsonDetails.Notes, e => e.PlainTextColumn) where JsonDetails is JSON-mapped and PlainTextColumn is a normal column.","commonSituations":"Trying to copy a value from one column into a JSON sub-property; modeling data migration via ExecuteUpdate that moves flat columns into JSON; using two entities sharing a table where one side is JSON.","solutions":["Assign a constant, a parameter, or another JSON scalar property to the JSON path instead of a regular column.","Project the source column value into the application first, then pass it as a parameter to ExecuteUpdate.","Perform the migration via raw SQL using the database's JSON functions if a server-side copy is mandatory."],"exampleFix":"// before (copying a flat column into a JSON path)\ndb.Records.ExecuteUpdate(s => s.SetProperty(\n    r => r.JsonData.Notes, r => r.LegacyNotes));\n\n// after (materialize the value client-side and pass as a constant/parameter)\nvar notes = await db.Records.Where(r => r.Id == id)\n    .Select(r => r.LegacyNotes).FirstAsync();\ndb.Records.Where(r => r.Id == id)\n    .ExecuteUpdate(s => s.SetProperty(\n        r => r.JsonData.Notes, notes));","handlingStrategy":"validation","validationCode":"// Before assigning a column to a JSON scalar path, materialize the source value client-side.\n// (No runtime API to detect this; guard by reviewing the SetProperty value lambda.)\n// Rule: JSON scalar SetProperty values must be constant/parameter/JSON-scalar only.","typeGuard":null,"tryCatchPattern":"try { await q.ExecuteUpdateAsync(s => s.SetProperty(e => e.Json.X, e => e.PlainCol)); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"non-JSON column\"))\n{ /* read PlainCol client-side and pass as parameter */ }","preventionTips":["Never assign a relational column directly into a JSON scalar path.","Materialize source values then pass them as parameters.","Use raw SQL with JSON_MODIFY-equivalents for server-side column-to-JSON copies."],"tags":["efcore","executeupdate","json","setproperty"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}