dotnet/efcore · error · NotSupportedException
The literal expression
Error message
The literal expression '{expression}' for '{type}' cannot be parsed. Only simple constructor calls and factory methods are supported. What it means
Thrown by CSharpHelper while scaffolding a design-time literal: the type mapping's GenerateCodeLiteral returned an expression tree whose shape the helper cannot render (it only understands simple constructor calls and static factory methods). This is a NotSupportedException raised during code generation for migrations/seeds or compiled-model literals.
Solutions
- Implement CoreTypeMapping.GenerateCodeLiteral on the custom type mapping to return a NewExpression or a static factory MethodCallExpression.
- If the literal is a default/discriminator/seed, replace the complex value with a primitive the scaffolder understands (string, int, GUID).
- Move the constant out of the model and apply it at runtime instead of via HasDefaultValue.
- Report the type to the provider author so GenerateCodeLiteral is supported upstream.
Example fix
// before - custom struct used as a default value produces an unmappable literal
modelBuilder.Entity<Foo>().Property(x => x.Custom).HasDefaultValue(CustomValue.Parse("abc"));
// after - generate a supported factory-method literal
public sealed class CustomValue
{
public static Expression GenerateCodeLiteral(object v)
=> Expression.Call(typeof(CustomValue).GetMethod(nameof(Parse))!,
Expression.Constant(((CustomValue)v).Raw));
} Defensive patterns
Strategy: validation
Validate before calling
var mapping = typeMappingSource.FindMapping(typeof(CustomValue));
if (mapping?.GenerateCodeLiteral(sample) is Expression e
&& !IsSimpleCtorOrFactory(e))
{
throw new InvalidOperationException(
"CustomValue literal cannot be scaffolded; implement GenerateCodeLiteral.");
} Type guard
static bool IsSimpleCtorOrFactory(Expression e)
=> e is NewExpression or MethodCallExpression { Object: null };
Try / catch
try { helper.UnknownLiteral(value); }
catch (NotSupportedException ex) when (ex.Message.Contains("cannot be parsed"))
{ /* fall back to a primitive constant or compute at runtime */ } Prevention
- Implement CoreTypeMapping.GenerateCodeLiteral for any custom mapped type used as a model constant.
- Avoid non-primitive defaults in the model; apply them in code.
- Run scaffolding in CI to catch literal-generation regressions early.
When it happens
Trigger: A value of a custom or third-party type is used as a model constant/default (HasDefaultValue, seed data, discriminator) and its CoreTypeMapping.GenerateCodeLiteral emits something other than NewExpression, factory MethodCallExpression, or a supported primitive expression. Nested complex expressions orMemberInit fall through HandleExpression and return false.
Common situations: Custom value converters whose target type has no code-literal support; NodaTime or other provider types used as column defaults; upgrading EF Core and a previously-supported literal shape is now rejected.
Related errors
- Cannot scaffold C# literals of type
- A type-qualified method call requires an instance…
- Failed to resolve type for directive processor
- Metadata model returned should not be 'null'. Provider
- No files were generated in directory
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/ab2ca9c4601d50aa.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Design/Design/Internal/CSharpHelper.cs:1107
var genericArguments = valueType.GetGenericArguments();
switch (value)
{
case IList list when genericArguments.Length == 1 && valueType.GetGenericTypeDefinition() == typeof(List<>):
return List(genericArguments[0], list);
case IDictionary dict when genericArguments.Length == 2 && valueType.GetGenericTypeDefinition() == typeof(Dictionary<,>):
return Dictionary(genericArguments[0], genericArguments[1], dict);
}
}
var mapping = _typeMappingSource.FindMapping(literalType);
if (mapping != null)
{
var builder = new StringBuilder();
var expression = mapping.GenerateCodeLiteral(value);
var handled = HandleExpression(expression, builder);
return !handled
? throw new NotSupportedException(
DesignStrings.LiteralExpressionNotSupported(
expression.ToString(),
literalType.ShortDisplayName()))
: builder.ToString();
}
throw new InvalidOperationException(DesignStrings.UnknownLiteral(literalType));
}
private bool HandleExpression(Expression expression, StringBuilder builder, bool simple = false)
{
// Only handle trivially simple cases for `new` and factory methods
switch (expression.NodeType)
{
case ExpressionType.NewArrayInit:
builder
.Append("new ")
.Append(Reference(expression.Type.GetElementType()!))View on GitHub (pinned to 3a2006ef56)