dotnet/efcore · error · InvalidOperationException

The parameter ' ' for the DbFunction ' ' has an invalid…

Error message

The parameter '{parameter}' for the DbFunction '{function}' has an invalid type '{type}'. Ensure the parameter type can be mapped by the current provider.

What it means

Thrown when any parameter of a DbFunction has a null TypeMapping, meaning the relational provider cannot translate the parameter's CLR type to a store column type. The loop at RelationalModelValidator.cs:402-412 iterates dbFunction.Parameters after the return-type checks and throws DbFunctionInvalidParameterType for the first parameter whose TypeMapping is null.

Solutions

  1. Change the DbFunction parameter to a primitive the provider maps (int, string, Guid, DateTime, decimal, byte[], etc.).
  2. If you must take an unsupported CLR type, split/wrap it: pass its serialized representation (e.g., string) and parse server-side or convert before calling.
  3. Register a value converter for the type at the model level so a mapping is found, or supply a custom IRelationalTypeMappingSource.
  4. Upgrade the provider package (Microsoft.Data.Sqlite / Npgsql / Pomelo / SqlServer) to a version that maps the type (e.g., DateOnly/TimeOnly).

Example fix

// before — ulong not mapped by SqlServer provider
public IQueryable<Order> OrdersAbove(ulong minId)
    => FromExpression(() => OrdersAbove(minId));

// after — pass a mapped type
public IQueryable<Order> OrdersAbove(long minId)
    => FromExpression(() => OrdersAbove(minId));
Defensive patterns

Strategy: validation

Validate before calling

// For each DbFunction parameter, confirm a relational type mapping exists.
var relational = modelBuilder.Model.GetRelationalModel();
foreach (var dbFn in modelBuilder.Model.GetDbFunctions())
{
    foreach (var p in dbFn.Parameters)
    {
        if (p.TypeMapping is null)
            throw new InvalidOperationException($"DbFunction '{dbFn.Name}' parameter '{p.Name}' (CLR {p.ClrType.Name}) has no provider mapping.");
    }
}

Try / catch

try { _ = ctx.Model; }
catch (InvalidOperationException ex) when (ex.Message.Contains("has an invalid type"))
{
    logger.LogError("DbFunction parameter type unmapped by provider. {Msg}", ex.Message);
    throw;
}

Prevention

When it happens

Trigger: Declaring a DbFunction method with a parameter type the provider doesn't natively support (e.g., a custom struct, object, ulong on some providers, an enum without conversion, an unmapped record). Also when a value converter is required but not registered, or the provider lacks a mapping for System.DateOnly/TimeOnly on older versions.

Common situations: Upgrading/downgrading the database provider so a previously-mapped type is no longer supported; passing a complex value type; using a domain enum that needs HasConversion<T>() at the parameter level; custom ITypeMappingSource plugins not loaded.

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/f0e54553e5fe2261. Report an issue: GitHub.

Appendix: source

Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:406

            {
                throw new InvalidOperationException(
                    RelationalStrings.DbFunctionInvalidReturnEntityType(
                        dbFunction.ModelName, dbFunction.ReturnType.ShortDisplayName(), elementType.ShortDisplayName()));
            }

            if ((entityType.BaseType != null || entityType.GetDerivedTypes().Any())
                && entityType.FindDiscriminatorProperty() == null)
            {
                throw new InvalidOperationException(
                    RelationalStrings.TableValuedFunctionNonTph(dbFunction.ModelName, entityType.DisplayName()));
            }
        }

        foreach (var parameter in dbFunction.Parameters)
        {
            if (parameter.TypeMapping == null)
            {
                throw new InvalidOperationException(
                    RelationalStrings.DbFunctionInvalidParameterType(
                        parameter.Name,
                        dbFunction.ModelName,
                        parameter.ClrType.ShortDisplayName()));
            }
        }
    }

    /// <summary>
    ///     Validates the function mapping for an entity type.
    /// </summary>
    /// <param name="entityType">The entity type to validate.</param>
    /// <param name="logger">The logger to use.</param>
    protected virtual void ValidateDbFunctionMapping(
        IEntityType entityType,
        IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
    {
        var mappedFunctionName = entityType.GetFunctionName();

View on GitHub (pinned to 3a2006ef56)