dotnet/machinelearning · error · InvalidOperationException

Bad type in ColumnTypeExtensions.NumberTypeFromType: {type}

Error message

Bad type in ColumnTypeExtensions.NumberTypeFromType: {type}

What it means

ColumnTypeExtensions.NumberTypeFromType converts a CLR numeric type to a NumberDataViewType. It first tries TryGetDataKind; if that fails, it asserts the internal invariant and throws InvalidOperationException 'Bad type in ColumnTypeExtensions.NumberTypeFromType: {type}', meaning the caller passed a CLR type that is not a recognized numeric data kind (e.g. bool, string, DateTime, Guid).

Source

Thrown at src/Microsoft.ML.Core/Data/ColumnTypeExtensions.cs:136

        if (kind == InternalDataKind.TS)
            return TimeSpanDataViewType.Instance;
        if (kind == InternalDataKind.DT)
            return DateTimeDataViewType.Instance;
        if (kind == InternalDataKind.DZ)
            return DateTimeOffsetDataViewType.Instance;
        if (kind == InternalDataKind.UG)
            return RowIdDataViewType.Instance;
        return NumberTypeFromKind(kind);
    }

    public static NumberDataViewType NumberTypeFromType(Type type)
    {
        InternalDataKind kind;
        if (type.TryGetDataKind(out kind))
            return NumberTypeFromKind(kind);

        Contracts.Assert(false);
        throw new InvalidOperationException($"Bad type in {nameof(ColumnTypeExtensions)}.{nameof(NumberTypeFromType)}: {type}");
    }

    private static NumberDataViewType NumberTypeFromKind(InternalDataKind kind)
    {
        switch (kind)
        {
            case InternalDataKind.I1:
                return NumberDataViewType.SByte;
            case InternalDataKind.U1:
                return NumberDataViewType.Byte;
            case InternalDataKind.I2:
                return NumberDataViewType.Int16;
            case InternalDataKind.U2:
                return NumberDataViewType.UInt16;
            case InternalDataKind.I4:
                return NumberDataViewType.Int32;
            case InternalDataKind.U4:
                return NumberDataViewType.UInt32;

View on GitHub (pinned to 7b76e69cf9)

Solutions

  1. Verify the type is a supported numeric primitive (byte/sbyte/short/ushort/int/uint/long/ulong/float/double/decimal) before calling NumberTypeFromType.
  2. Use PrimitiveTypeFromType instead, which handles non-numeric primitives (bool, string, DateTime, etc.).
  3. Map non-numeric types explicitly (e.g. TextDataViewType.Instance for string) before conversion.
  4. Catch InvalidOperationException and fall back to a type-lookup table of your own.

Example fix

// before
var numberType = ColumnTypeExtensions.NumberTypeFromType(typeof(bool));
// after
var viewType = typeof(bool) == type ? BooleanDataViewType.Instance
    : ColumnTypeExtensions.PrimitiveTypeFromType(type);
Defensive patterns

Strategy: type-guard

Validate before calling

private static readonly HashSet<Type> NumericTypes = new HashSet<Type> {
    typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int),
    typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double) };
if (!NumericTypes.Contains(type))
    throw new ArgumentException($"{type} is not a numeric DataView type");

Type guard

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

Try / catch

try
{
    numberType = ColumnTypeExtensions.NumberTypeFromType(clrType);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("NumberTypeFromType"))
{
    numberType = null; // fall back to PrimitiveTypeFromType or a lookup table
}

Prevention

When it happens

Trigger: Calling NumberTypeFromType(typeof(bool)) / typeof(string) / typeof(DateTime) / typeof(char) / typeof(Guid) directly; or PrimitiveTypeFromType receiving a non-primitive-numeric type and delegating to NumberTypeFromType.

Common situations: Building custom IDataView pipelines or schema builders where a column's CLR type isn't numeric but the code assumes it is; mapping user data types to DataView types without a prior whitelist check.

Related errors


AI-assisted analysis of dotnet/machinelearning@7b76e69cf9 (2026-09-11). Data as JSON: /api/errors/df2829b4eb58b6a5. Report an issue: GitHub.