dotnet/machinelearning · error · ArgumentException
getter must be of type '{typeof(ValueGetter<TValue>).FullNam
Error message
getter must be of type '{typeof(ValueGetter<TValue>).FullName}' What it means
Builder.AddDelegate casts the getter delegate to ValueGetter<TValue> and throws ArgumentException("getter must be of type 'ValueGetter<TValue>'") when the cast fails. The builder requires a typed ValueGetter<TValue> delegate to store values into the schema column; any other delegate signature cannot be used. Note the Debug.Asserts indicate this method is internal/contractually pre-validated, so this mostly surfaces from dynamic invocation.
Source
Thrown at src/Microsoft.ML.DataView/DataViewSchema.cs:369
/// Returns a <see cref="Annotations"/> row that contains the current contents of this <see cref="Builder"/>.
/// </summary>
public Annotations ToAnnotations()
{
var builder = new DataViewSchema.Builder();
foreach (var item in _items)
builder.AddColumn(item.Name, item.Type, item.Annotations);
return new Annotations(builder.ToSchema(), _items.Select(x => x.Getter).ToArray());
}
private void AddDelegate<TValue>(string name, DataViewType type, Delegate getter, Annotations annotations)
{
Debug.Assert(!string.IsNullOrEmpty(name));
Debug.Assert(type != null);
Debug.Assert(getter != null);
var typedGetter = getter as ValueGetter<TValue>;
if (typedGetter == null)
throw new ArgumentException($"{nameof(getter)} must be of type '{typeof(ValueGetter<TValue>).FullName}'", nameof(getter));
_items.Add((name, type, typedGetter, annotations));
}
}
}
/// <summary>
/// Class containing operations to build a <see cref="DataViewSchema"/>.
/// </summary>
public sealed class Builder
{
private readonly List<(string Name, DataViewType Type, Annotations Annotations)> _items;
/// <summary>
/// Create a new instance of <see cref="Builder"/>.
/// </summary>
public Builder()
{
_items = new List<(string Name, DataViewType Type, Annotations Annotations)>();View on GitHub (pinned to 7b76e69cf9)
Solutions
- Supply a ValueGetter<TValue> delegate: (ref TValue dst) => dst = value, not Func/Action with different signatures.
- Ensure the generic type argument matches the getter's type argument (ValueGetter<int> for TValue=int).
- When using reflection, call Delegate.CreateDelegate(typeof(ValueGetter<T>), target, method) with the correct T.
- Cast defensively: if (getter is ValueGetter<TValue> g) builder.AddDelegate(...) else throw a clear error.
Example fix
// before
builder.AddDelegate("Score", NumberDataViewType.Single, (float) => GetScore());
// after
float GetScore(ref float dst) { dst = ComputeScore(); }
builder.AddDelegate("Score", NumberDataViewType.Single, (ValueGetter<float>)GetScore); Defensive patterns
Strategy: type-guard
Validate before calling
if (!(getter is ValueGetter<TValue>)) throw new ArgumentException("getter must be a ValueGetter<TValue>"); Type guard
bool IsTypedGetter<TV>(Delegate d) => d is ValueGetter<TV>;
Try / catch
try { builder.AddDelegate(name, type, getter); } catch (ArgumentException) { /* rebuild delegate as ValueGetter<TValue> */ } Prevention
- Always write getters with the void(ref TValue) signature
- Use explicit (ValueGetter<TValue>) casts so the compiler catches mismatches
- Create reflection delegates with Delegate.CreateDelegate(typeof(ValueGetter<T>), ...)
When it happens
Trigger: Passing a lambda or method group convertible to Func<TValue> but not to ValueGetter<TValue> (whose signature is void(ref TValue)), e.g. AddDelegate(name, type, (out int v) => ...) or a Delegate obtained via reflection/Delegate.CreateDelegate with the wrong signature.
Common situations: Reflection-based schema construction where the delegate was created against the wrong generic type argument; wrapping existing getters with incompatible anonymous delegates; generic helpers passing Delegate objects.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- columns
- rawType
- A PrimitiveDataViewType cannot have a disposable RawType
- Not implemented type {typeof(T)}
- The input tokenizer is not using the EnglishRoberta model.
AI-assisted analysis of dotnet/machinelearning@7b76e69cf9 (2026-09-11).
Data as JSON: /api/errors/8172943ff4ebf422.
Report an issue: GitHub.