dotnet/efcore · error · InvalidOperationException
'ExecuteUpdate' cannot currently set a property in a JSON co
Error message
'ExecuteUpdate' cannot currently set a property in a JSON column to a regular, non-JSON column; see https://github.com/dotnet/efcore/issues/36688.
What it means
Thrown inside the JsonScalarExpression case when TrySerializeScalarToJson fails and the value being assigned is a ColumnExpression. EF Core cannot set a JSON column's nested property to the value of a different, non-JSON column — the JSON modification functions only accept JSON-serialized scalars. Tracked by issue #36688.
Source
Thrown at src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs:391
var typeMapping = jsonScalar.TypeMapping;
Check.DebugAssert(typeMapping is not null);
// We should never see a JsonScalarExpression without a path - that means we're mapping a JSON scalar directly to a relational column.
// This is in theory possible (e.g. map a DateTime to a 'json' column with a single string timestamp representation inside, instead of to
// SQL Server datetime2), but contrived and unsupported.
Check.DebugAssert(jsonScalar.Path.Count > 0);
ProcessColumn(jsonColumn, targetProperty);
var translatedValue = TranslateScalarSetterValueSelector(source, valueSelector, jsonScalar.Type, typeMapping);
// We now have the relational scalar expression for the value; but we need the JSON representation to pass to the provider's JSON modification
// function (e.g. SQL Server JSON_MODIFY()).
// For example, for a DateTime we'd have e.g. a SqlConstantExpression containing a DateTime instance, but we need a string containing
// the JSON-encoded ISO8601 representation.
if (!TrySerializeScalarToJson(jsonScalar, translatedValue, out var jsonValue))
{
throw new InvalidOperationException(
translatedValue is ColumnExpression
? RelationalStrings.ExecuteUpdateCannotSetJsonPropertyToNonJsonColumn
: RelationalStrings.ExecuteUpdateCannotSetJsonPropertyToArbitraryExpression);
}
// We now have a serialized JSON value (number, string or bool) - generate a setter for it.
GenerateJsonPartialUpdateSetterWrapper(jsonScalar, jsonColumn, jsonValue);
continue;
}
case StructuralTypeShaperExpression { ValueBufferExpression: JsonQueryExpression jsonQuery }:
ProcessStructuralJsonSetter(jsonQuery);
continue;
case CollectionResultExpression { QueryExpression: JsonQueryExpression jsonQuery }:
ProcessStructuralJsonSetter(jsonQuery);
continue;
View on GitHub (pinned to 3a2006ef56)
Solutions
- Split the operation: read the source value first, then ExecuteUpdate with a parameter/constant serialized into the JSON path.
- Restructure so the JSON property is updated from a constant or parameter only (supported paths).
- Track #36688 for future support of column-to-JSON assignments.
Example fix
// before
await ctx.Set<Root>().ExecuteUpdateAsync(s =>
s.SetProperty(r => r.Config.Enabled, r => r.TmpFlag));
// after
var flag = await ctx.Set<Root>().Select(r => r.TmpFlag).FirstAsync();
await ctx.Set<Root>().ExecuteUpdateAsync(s =>
s.SetProperty(r => r.Config.Enabled, flag)); Defensive patterns
Strategy: validation
Validate before calling
// Detect column-source value selectors into JSON paths. // Heuristic: if the value selector references a property of a different entity/table than the JSON owner, read it first. var src = await ctx.Set<Root>().Select(r => r.TmpFlag).FirstAsync(); await ctx.Set<Root>().ExecuteUpdateAsync(s => s.SetProperty(r => r.Config.Enabled, src));
Prevention
- Never reference another entity's column inside a JSON-path value selector.
- Read the source value client-side and pass it as a parameter.
- Track issue #36688 for native support.
When it happens
Trigger: ExecuteUpdate with SetProperty pointing at a JSON scalar path and a value selector that projects a column from another table: SetProperty(e => e.JsonConfig.SomeFlag, e => e.OtherEntity.SomeFlag). The Sqlite tests (SqliteMiscellaneousTypeTest, SqliteTemporalTypeTest) assert this message.
Common situations: Trying to copy a value from a relational column into a JSON path in one ExecuteUpdate; cross-column assignments involving JSON.
Related errors
- '{operation}' used over owned type '{entityType}' which is m
- 'ExecuteUpdate' is being used over type '{structuralType}' w
- 'ExecuteUpdate' cannot currently set a property in a JSON co
- ExecuteUpdate over JSON columns is not supported when the co
- The provider in use does not support partial updates with Ex
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/9d6aaf49b5f8ba13.
Report an issue: GitHub.