dotnet/efcore · error · InvalidOperationException

Unsupported numeric type mapping: '{type}'.

Error message

Unsupported numeric type mapping: '{type}'.

What it means

CosmosNumberProjectionTypeMapping.CreateFromType is a factory mapping CLR numeric types to specialized CosmosNumberProjectionTypeMapping<T> instances. It supports int, long, short, sbyte, float, uint, ulong, ushort, byte. Any other Type throws InvalidOperationException with an interpolated message listing the unsupported type. This is internal-API misuse: the model pipeline handed in a numeric type the provider does not handle.

Source

Thrown at src/EFCore.Cosmos/Storage/Internal/CosmosNumberProjectionTypeMapping.cs:32

public static class CosmosNumberProjectionTypeMapping
{
    /// <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 static CosmosTypeMapping CreateFromType(Type type)
        => type == typeof(int) ? CosmosNumberProjectionTypeMapping<int>.Default
            : type == typeof(long) ? CosmosNumberProjectionTypeMapping<long>.Default
            : type == typeof(short) ? CosmosNumberProjectionTypeMapping<short>.Default
            : type == typeof(sbyte) ? CosmosNumberProjectionTypeMapping<sbyte>.Default
            : type == typeof(float) ? CosmosNumberProjectionTypeMapping<float>.Default
            : type == typeof(uint) ? CosmosNumberProjectionTypeMapping<uint>.Default
            : type == typeof(ulong) ? CosmosNumberProjectionTypeMapping<ulong>.Default
            : type == typeof(ushort) ? CosmosNumberProjectionTypeMapping<ushort>.Default
            : type == typeof(byte) ? CosmosNumberProjectionTypeMapping<byte>.Default
            : throw new InvalidOperationException($"Unsupported numeric type mapping: '{type}'.");

    /// <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 static bool IsRequiredForType(Type type)
        => type == typeof(int)
            || type == typeof(long)
            || type == typeof(short)
            || type == typeof(sbyte)
            || type == typeof(float)
            || type == typeof(uint)
            || type == typeof(ulong)
            || type == typeof(ushort)
            || type == typeof(byte);
}

View on GitHub (pinned to 3a2006ef56)

Solutions

  1. Map decimal/double properties with a value converter to a supported numeric type (e.g. long or int), or store them as strings.
  2. If you reached this via reflection/internal API, pass only one of the supported types (int, long, short, sbyte, float, uint, ulong, ushort, byte).
  3. File an issue / use a different mapping strategy if a genuine double projection is required.

Example fix

// before
modelBuilder.Entity<Sample>().Property(s => s.Amount).HasColumnType("decimal");
// internal pipeline calls CreateFromType(typeof(decimal)) -> throws

// after - convert to a supported numeric type
modelBuilder.Entity<Sample>()
    .Property(s => s.Amount)
    .HasConversion(v => (long)(v * 100), v => (decimal)v / 100m);
Defensive patterns

Strategy: validation

Validate before calling

static readonly HashSet<Type> Supported = new()
{ typeof(int), typeof(long), typeof(short), typeof(sbyte),
  typeof(float), typeof(uint), typeof(ulong), typeof(ushort), typeof(byte) };

foreach (var prop in dbContext.Model.GetEntityTypes().SelectMany(t => t.GetProperties()))
{
    var clr = prop.ClrType.UnwrapNullable();
    if (!Supported.Contains(clr) && clr.IsNumeric())
        throw new InvalidOperationException($"{prop.Name} maps unsupported numeric {clr}.");
}

Type guard

static bool IsSupportedCosmosNumeric(Type t)
    => t == typeof(int) || t == typeof(long) || t == typeof(short) || t == typeof(sbyte)
       || t == typeof(float) || t == typeof(uint) || t == typeof(ulong)
       || t == typeof(ushort) || t == typeof(byte);

Prevention

When it happens

Trigger: Internal code (or a custom type mapping) calls CreateFromType with an unsupported numeric CLR type such as double, decimal, or char. Most commonly reached when a property of type double/decimal is configured for Cosmos projection.

Common situations: Mapping a decimal or double property in a way that routes through the numeric projection path. Custom value converters or type mappings that surface an unsupported numeric type. Provider bug after a model change.

Related errors


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