dotnet/efcore · error · InvalidOperationException
'IsNullable' cannot be set on DbFunction '{functionName}' si
Error message
'IsNullable' cannot be set on DbFunction '{functionName}' since the function does not represent a scalar function. What it means
Thrown by DbFunction.SetIsNullable when IsScalar is false (the function returns IQueryable<T>, i.e. it is a table-valued function). Nullability of a return value only makes sense for scalar functions; a TVF returns a row set, so 'nullable' is meaningless and EF rejects the configuration.
Source
Thrown at src/EFCore.Relational/Metadata/Internal/DbFunction.cs:476
public virtual bool IsNullable
{
get => _nullable;
set => SetIsNullable(value, ConfigurationSource.Explicit);
}
/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual bool SetIsNullable(bool nullable, ConfigurationSource configurationSource)
{
EnsureMutable();
if (!IsScalar)
{
throw new InvalidOperationException(RelationalStrings.NonScalarFunctionCannotBeNullable(Name));
}
_nullable = nullable;
_nullableConfigurationSource = configurationSource.Max(_nullableConfigurationSource);
return nullable;
}
/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual ConfigurationSource? GetIsNullableConfigurationSource()
=> _nullableConfigurationSource;
/// <summary>View on GitHub (pinned to dbf9771522)
Solutions
- Remove the IsNullable call for table-valued functions; only set it for scalar DbFunctions.
- Guard the call: only apply IsNullable when the function is scalar.
- Split configuration into scalar vs TVF branches so TVFs skip nullability.
- If you intended a scalar function, change the return type to a scalar type first.
Example fix
// before
public IQueryable<Order> RecentOrders() => /* tvf */;
modelBuilder.HasDbFunction(typeof(Ctx).GetMethod("RecentOrders"))
.HasAnnotation(RelationalAnnotationNames.DbFunctionIsNullable, true); // throws
// after
public IQueryable<Order> RecentOrders() => /* tvf */;
modelBuilder.HasDbFunction(typeof(Ctx).GetMethod("RecentOrders"));
// (do not set IsNullable on a TVF) Defensive patterns
Strategy: validation
Validate before calling
// Only apply IsNullable to scalar functions
foreach (var fn in modelBuilder.Model.GetDbFunctions().Where(f => f.IsScalar))
{
fn.Builder.IsNullable(true, fromDataAnnotation: true);
} Type guard
static bool CanSetNullable(IDbFunction fn) => fn.IsScalar;
Prevention
- Branch DbFunction configuration by IsScalar (scalar vs TVF).
- Do not run shared 'configure all DbFunctions' helpers that set IsNullable blindly.
- Document which DbFunctions are scalar vs TVF near their declarations.
When it happens
Trigger: Calling builder.IsNullable(...) (HasAnnotation/IsNullable fluent) on a DbFunction that returns IQueryable<T>. Surfaced through InternalDbFunctionBuilder.IsNullable -> Metadata.SetIsNullable.
Common situations: Developers apply a generic DbFunction configuration helper that sets IsNullable to every registered function, including TVFs. Or copy scalar-function config onto a TVF.
Related errors
- 'PropagatesNullability' cannot be set on parameter '{paramet
- The DbFunction '{function}' has an invalid return type '{typ
- Custom translation cannot be set on the DbFunction '{functio
- The DbFunction '{function}' is generic. Mapping generic meth
- The DbFunction '{function}' defined on type '{type}' must be
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/4d30e0fa0957e309.
Report an issue: GitHub.