dotnet/efcore · error · InvalidOperationException
The DbFunction ' ' has an invalid return type ' '. Ensure…
Error message
The DbFunction '{function}' has an invalid return type '{type}'. Ensure that the return type can be mapped by the current provider. What it means
ValidateDbFunction throws DbFunctionInvalidReturnType when a scalar DbFunction has no resolved type mapping (dbFunction.TypeMapping == null). The provider could not map the function's return type to a store type, meaning the CLR return type is unsupported by the current provider. Distinct from the IQueryable-return variant (359) which targets owned-entity returns.
Solutions
- Change the DbFunction's return type to one the provider maps natively (int, string, DateTime, double, etc.).
- Register a value converter / type mapping for the custom return type before defining the DbFunction.
- If wrapping a database function returning an exotic type, expose it through a SQL view or compute a primitive in the method body.
Example fix
// before — MoneyAmount is a custom struct with no mapping
public static MoneyAmount Total(this DbContext db, int id)
=> throw new NotImplementedException();
modelBuilder.HasDbFunction(typeof(MyCtx).GetMethod(nameof(MyCtx.Total))!); // throws
// after — return decimal, convert at the call site
public static decimal Total(this DbContext db, int id)
=> throw new NotImplementedException(); Defensive patterns
Strategy: validation
Validate before calling
if (dbFunction.IsScalar && dbFunction.TypeMapping is null)
throw new InvalidOperationException($"DbFunction {dbFunction.ModelName} return type {dbFunction.ReturnType} has no mapping."); Type guard
static bool HasScalarMapping(IDbFunction f)
=> !f.IsScalar || f.TypeMapping is not null; Prevention
- Use provider-mappable return types for scalar DbFunctions (int, string, DateTime, double).
- Register value converters / mappings for custom return types before HasDbFunction.
- Validate DbFunction return types in a model-finalization unit test.
When it happens
Trigger: Registering HasDbFunction for a method whose return CLR type has no relational type mapping — e.g. a custom struct, an unsupported primitive, or a type whose mapping requires a value converter not configured for DbFunction resolution. Only fires when dbFunction.IsScalar and TypeMapping is null.
Common situations: Using a provider-specific function returning a type the provider doesn't map by default (e.g. timespan, char, decimal with unusual scale); registering a DbFunction whose return type is a domain enum without configuring the enum conversion; upgrading the provider and losing a previously-inferred mapping.
Related errors
- The parameter ' ' for the DbFunction ' ' has an invalid…
- Model building is not supported when publishing with…
- Model building is not supported when publishing with…
- The DbFunction ' ' has an invalid return type ' '. Owned…
- The DbFunction ' ' returns ' ', but ' ' is not a mapped…
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/bff5dd2f20ee7cb6.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:367
IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
{
}
/// <summary>
/// Validates a single database function.
/// </summary>
/// <param name="dbFunction">The database function to validate.</param>
/// <param name="logger">The logger to use.</param>
protected virtual void ValidateDbFunction(
IDbFunction dbFunction,
IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
{
var model = dbFunction.Model;
if (dbFunction.IsScalar)
{
if (dbFunction.TypeMapping == null)
{
throw new InvalidOperationException(
RelationalStrings.DbFunctionInvalidReturnType(
dbFunction.ModelName,
dbFunction.ReturnType.ShortDisplayName()));
}
}
else
{
var elementType = dbFunction.ReturnType.GetGenericArguments()[0];
var entityType = model.FindEntityType(elementType);
if (entityType?.IsOwned() == true
|| ((IConventionModel)model).IsOwned(elementType)
|| (entityType == null && model.GetEntityTypes().Any(e => e.ClrType == elementType)))
{
throw new InvalidOperationException(
RelationalStrings.DbFunctionInvalidIQueryableOwnedReturnType(
dbFunction.ModelName, elementType.ShortDisplayName()));
}View on GitHub (pinned to 3a2006ef56)