dotnet/machinelearning · error · ArgumentNullException
selector
Error message
selector
What it means
The DataViewSchema.Builder.Add(Annotations, Func<string,bool>) overload requires a non-null selector predicate that decides which annotation columns to copy. Passing null is treated as a programming error, so the builder throws ArgumentNullException named 'selector'.
Source
Thrown at src/Microsoft.ML.DataView/DataViewSchema.cs:277
public Builder()
{
_items = new List<(string Name, DataViewType Type, Delegate Getter, Annotations Annotations)>();
}
/// <summary>
/// Add some columns from <paramref name="annotations"/> into our new annotations, by applying <paramref name="selector"/>
/// to all the names.
/// </summary>
/// <param name="annotations">The annotations row to take values from.</param>
/// <param name="selector">The predicate describing which annotation columns to keep.</param>
public void Add(Annotations annotations, Func<string, bool> selector)
{
if (annotations == null)
return;
if (selector == null)
throw new ArgumentNullException(nameof(selector));
foreach (var column in annotations.Schema)
{
if (selector(column.Name))
_items.Add((column.Name, column.Type, annotations.GetGetterInternal(column.Index), column.Annotations));
}
}
/// <summary>
/// Add one annotation column, strongly-typed version.
/// </summary>
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <param name="name">The annotation name.</param>
/// <param name="type">The annotation type.</param>
/// <param name="getter">The getter delegate.</param>
/// <param name="annotations">Annotations of the input column. Note that annotations on an annotation column is somewhat rare
/// except for certain types (for example, slot names for a vector, key values for something of key type).</param>
public void Add<TValue>(string name, DataViewType type, ValueGetter<TValue> getter, Annotations annotations = null)View on GitHub (pinned to 7b76e69cf9)
Solutions
- Pass a predicate that accepts everything if you want all annotations: name => true
- Only call the overload when you genuinely have a filter; otherwise use the non-selective copy path
- Assert or default the selector before calling: selector ?? (_ => true)
Example fix
// before builder.Add(inputAnnotations, null); // after builder.Add(inputAnnotations, name => true);
Defensive patterns
Strategy: validation
Validate before calling
if (selector == null)
selector = name => true;
builder.Add(sourceAnnotations, selector); Try / catch
try { builder.Add(annotations, selector); }
catch (ArgumentNullException e) when (e.ParamName == "selector")
{
builder.Add(annotations, _ => true);
} Prevention
- Never pass null where a Func<string,bool> is expected; use _ => true for 'copy all'
- Null-check optional predicate parameters before forwarding them
- Prefer the selective Add overload only when a real filter exists
When it happens
Trigger: Calling builder.Add(sourceAnnotations, null); forwarding a selector variable that is null because an upstream branch never assigned it; generic helper code that passes through an optional predicate without defaulting it.
Common situations: Writing a custom IDataView transform that copies a subset of annotations and mistakenly believing null means 'copy all'; refactoring where a previously always-set lambda became conditionally null.
Related errors
- name
- type
- getter
- The provided model file {filePath} doesn't exist.
- Start must be called on a ModelLoader before it can be used.
AI-assisted analysis of dotnet/machinelearning@7b76e69cf9 (2026-09-11).
Data as JSON: /api/errors/a4989936c0db5751.
Report an issue: GitHub.