dotnet/efcore · error · InvalidOperationException
Cannot scaffold C# literals of type
Error message
Cannot scaffold C# literals of type '{literalType}'. The provider should implement CoreTypeMapping.GenerateCodeLiteral to support using it at design time. What it means
Thrown by CSharpHelper.UnknownLiteral when no CoreTypeMapping can be found for the literal type at all — FindMapping returns null, so there is nothing capable of producing code for the value. InvalidOperationException, surfaced while generating literals for migrations, seeds, or the compiled model.
Solutions
- Register a value converter for the property so it maps to a primitive the provider understands.
- Avoid using the un-mapped type as HasDefaultValue/seed data; compute it at runtime instead.
- Update the provider package to a version that ships a mapping for the type.
- Implement and register an ITypeMappingSource plugin that returns a mapping for the literal type.
Example fix
// before
modelBuilder.Entity<T>().Property(x => x.Custom).HasDefaultValue(new CustomStruct());
// after - convert to a mapped primitive and apply default at runtime
modelBuilder.Entity<T>()
.Property(x => x.Custom)
.HasConversion(v => v.Serialize(), s => CustomStruct.Deserialize(s)); Defensive patterns
Strategy: validation
Validate before calling
var mapping = typeMappingSource.FindMapping(literalType);
if (mapping is null)
{
throw new InvalidOperationException(
$"No type mapping for {literalType}; register a value converter or pick a mapped type.");
} Type guard
static bool TypeIsMapped(ITypeMappingSource src, Type t)
=> src.FindMapping(t) is not null;
Try / catch
try { helper.UnknownLiteral(value); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Cannot scaffold"))
{ /* register a converter or remove the literal */ } Prevention
- Register value converters for custom value objects used in the model.
- Keep provider packages updated so mappings cover newer CLR types.
- Do not use unmapped CLR types as HasDefaultValue or seed values.
When it happens
Trigger: Using a value type as a constant/default/seed for which neither EF Core nor the active provider registers a type mapping. Common with clr types the provider does not natively map (e.g. Half, DateOnly on older providers, custom structs without a converter).
Common situations: Upgrading the database provider to a version that no longer maps a type, switching providers (SQL Server -> PostgreSQL) where a previously-mapped type is unsupported, or introducing a custom value object as a column default without a converter.
Related errors
- The literal expression
- 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/c942181484d0cd43.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Design/Design/Internal/CSharpHelper.cs:1114
}
}
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()!))
.Append("[] { ");
HandleList(((NewArrayExpression)expression).Expressions, builder, simple: true);
builder
.Append(" }");
View on GitHub (pinned to 3a2006ef56)