dotnet/machinelearning · error · InvalidOperationException
Invalid call to 'GetGetter'
Error message
Invalid call to 'GetGetter'
What it means
DataViewSchema.GetGetter<TValue> returns the typed ValueGetter<TValue> for a column, but the stored getter for that column index is either not a ValueGetter<TValue> of the requested type or is null. This means the caller asked for the column's value with a TValue that does not match the column's declared type. The library throws because returning null would silently break downstream row cursors.
Source
Thrown at src/Microsoft.ML.DataView/DataViewSchema.cs:229
private void CheckGetter<TValue>(Delegate getter)
{
var typedGetter = getter as ValueGetter<TValue>;
if (typedGetter == null)
throw new ArgumentNullException(nameof(getter), $"Getter of type '{typeof(TValue)}' expected, but {getter.GetType()} found");
}
/// <summary>
/// Get a getter delegate for one value of the annotations row.
/// </summary>
public ValueGetter<TValue> GetGetter<TValue>(DataViewSchema.Column column)
{
if (column.Index >= _getters.Length)
throw new ArgumentException(nameof(column));
var typedGetter = _getters[column.Index] as ValueGetter<TValue>;
if (typedGetter == null)
{
Debug.Assert(_getters[column.Index] != null);
throw new InvalidOperationException($"Invalid call to '{nameof(GetGetter)}'");
}
return typedGetter;
}
/// <summary>
/// Get the value of an annotation, by annotation kind (aka column name).
/// </summary>
public void GetValue<TValue>(string kind, ref TValue value)
{
var column = Schema.GetColumnOrNull(kind);
if (column == null)
throw new InvalidOperationException($"Invalid call to '{nameof(GetValue)}'");
GetGetter<TValue>(column.Value)(ref value);
}
public override string ToString() => string.Join(", ", Schema.Select(x => x.Name));
internal Delegate GetGetterInternal(int index)View on GitHub (pinned to 7b76e69cf9)
Solutions
- Check column.Type.RawType (or GetAnnotationType) and use exactly that type as TValue in GetGetter<TValue>
- Use the weakly-typed GetGetterInternal/Delegate path and convert with Utils.MarshalActionInvoke (or MarshalInvoke) instead of a fixed generic
- Inspect the column's DataViewType and slot structure before writing the cursor loop; if the type is dynamic, dispatch per-type
Example fix
// before
var getter = schema.GetGetter<int>(schema["Features"]);
// after
if (schema["Features"].Type.RawType == typeof(VBuffer<float>))
var getter = schema.GetGetter<VBuffer<float>>(schema["Features"]); Defensive patterns
Strategy: type-guard
Validate before calling
var col = schema["Features"];
if (col.Type.RawType != typeof(VBuffer<float>))
throw new InvalidOperationException($"Expected VBuffer<float>, got {col.Type.RawType}");
var getter = schema.GetGetter<VBuffer<float>>(col); Type guard
bool IsTyped<TValue>(DataViewSchema.Column c) => c.Type.RawType == typeof(TValue);
Try / catch
try { getter = schema.GetGetter<TValue>(col); }
catch (InvalidOperationException)
{
var actual = col.Type.RawType;
getter = MarshalGetter<TValue>(col, actual); // dispatch on actual type
} Prevention
- Always check column.Type.RawType before choosing TValue for GetGetter
- Never hard-code generic types for dynamically-typed columns
- Use GetGetterInternal + MarshalActionInvoke for weakly-typed cursor code
- Re-verify types after pipeline changes; transforms can alter column types
When it happens
Trigger: Calling schema.GetGetter<int>(col) on a column whose actual value type is float/ReadOnlyMemory<char>/VBuffer<etc>; casting a weakly-typed Delegate getter to the wrong ValueGetter<TValue>; reusing a getter obtained from a different schema after a transform changed column types.
Common situations: Hand-rolling a row cursor over a DataView and hard-coding a TValue; using GetGetter inside annotation/annotation-kind lookups with a mismatched generic; code written against one pipeline version breaking after upstream transforms change a column's type.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- {DefaultColumnNames.Features} column must be of data type {N
- type.RawType must be of type '{typeof(TValue).FullName}'.
- String.Format(Strings.MismatchedColumnValueType, this.DataTy
- Strings.BadColumnCast (formatted with column.DataType, typeo
- Strings.BadColumnCast (formatted with column.DataType, typeo
AI-assisted analysis of dotnet/machinelearning@7b76e69cf9 (2026-09-11).
Data as JSON: /api/errors/3571ab402bf46ec3.
Report an issue: GitHub.