dotnet/machinelearning · error · ArgumentException

unknown type

Error message

unknown type

What it means

NumericOptionConverter.Write serializes a UniformNumericOption to its schema JSON by switching on the runtime type (UniformIntOption/UniformSingleOption/UniformDoubleOption). If the value is a numeric option of another derived type, the default arm throws ArgumentException 'unknown type'.

Source

Thrown at src/Microsoft.ML.SearchSpace/Converter/NumericOptionConverter.cs:78

                    LogBase = intOption.LogBase,
                },
                UniformDoubleOption doubleOption => new Schema
                {
                    Type = "double",
                    Default = doubleOption.SampleFromFeatureSpace(doubleOption.Default).AsType<double>(),
                    Min = doubleOption.Min,
                    Max = doubleOption.Max,
                    LogBase = doubleOption.LogBase,
                },
                UniformSingleOption singleOption => new Schema
                {
                    Type = "float",
                    Default = singleOption.SampleFromFeatureSpace(singleOption.Default).AsType<Single>(),
                    Min = Convert.ToSingle(singleOption.Min),
                    Max = Convert.ToSingle(singleOption.Max),
                    LogBase = singleOption.LogBase,
                },
                _ => throw new ArgumentException("unknown type"),
            };

            JsonSerializer.Serialize(writer, schema, options);
        }
    }
}

View on GitHub (pinned to 7b76e69cf9)

Solutions

  1. Serialize only built-in UniformIntOption/UniformSingleOption/UniformDoubleOption instances.
  2. If you have a custom subclass, convert it to a base type (e.g. copy Min/Max/Default into a UniformDoubleOption) before serialization.
  3. Extend/patch the converter's switch to handle your derived type.
  4. Check that the object placed in the search space is actually the intended numeric option type.

Example fix

// before
OptionBase opt = new MyCustomNumericOption(...);
JsonSerializer.Serialize(writer, opt, options); // throws
// after
var asDouble = new UniformDoubleOption(opt.Min, opt.Max, false, opt.Default);
JsonSerializer.Serialize(writer, asDouble, options);
Defensive patterns

Strategy: type-guard

Validate before calling

// C#: only serialize known numeric option types
static bool IsSerializableNumericOption(OptionBase o) =>
    o is UniformIntOption or UniformSingleOption or UniformDoubleOption;

Type guard

static bool IsBuiltInNumericOption(OptionBase o) =>
    o is UniformIntOption or UniformSingleOption or UniformDoubleOption;

Try / catch

try { JsonSerializer.Serialize(writer, value, options); }
catch (ArgumentException ex) when (ex.Message == "unknown type")
{
    // convert the derived option to a base Uniform*Option and retry
}

Prevention

When it happens

Trigger: Serializing an OptionBase value that is a UniformNumericOption subclass not handled by the switch (e.g. a custom derived option type), via JsonSerializer with OptionConverter registered.

Common situations: Defining a custom numeric option subclass and putting it in a SearchSpace that gets serialized; library version mismatch where a new option type exists but the converter wasn't updated; putting the wrong object in a field typed as numeric option.

Related errors


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