dotnet/machinelearning · error · System.InvalidCastException
Cannot cast elements of column '{0}' type of {1} to type {2}
Error message
Cannot cast elements of column '{0}' type of {1} to type {2} used as TKey in grouping What it means
GroupBy<TKey> first calls the string-based GroupBy and casts the result to GroupBy<TKey>; when the column's DataType cannot be cast to TKey, the cast yields null and the method throws InvalidCastException with Strings.BadColumnCastDuringGrouping, naming the column, its actual type, and the requested TKey. It means the generic type parameter does not match the column's element type.
Source
Thrown at src/Microsoft.Data.Analysis/DataFrame.cs:390
DataFrameColumn column = _columnCollection[columnIndex];
return column.GroupBy(columnIndex, this);
}
/// <summary>
/// Groups the rows of the <see cref="DataFrame"/> by unique values in the <paramref name="columnName"/> column.
/// </summary>
/// <typeparam name="TKey">Type of column used for grouping</typeparam>
/// <param name="columnName">The column used to group unique values</param>
/// <returns>A GroupBy object that stores the group information.</returns>
public GroupBy<TKey> GroupBy<TKey>(string columnName)
{
GroupBy<TKey> group = GroupBy(columnName) as GroupBy<TKey>;
if (group == null)
{
DataFrameColumn column = this[columnName];
throw new InvalidCastException(String.Format(Strings.BadColumnCastDuringGrouping, columnName, column.DataType, typeof(TKey)));
}
return group;
}
// In GroupBy and ReadCsv calls, columns get resized. We need to set the RowCount to reflect the true Length of the DataFrame. This does internal validation
internal void SetTableRowCount(long rowCount)
{
// Even if current RowCount == rowCount, do the validation
for (int i = 0; i < Columns.Count; i++)
{
if (Columns[i].Length != rowCount)
throw new ArgumentException(String.Format("{0} {1}", Strings.MismatchedRowCount, Columns[i].Name));
}
_columnCollection.RowCount = rowCount;
}
/// <summary>View on GitHub (pinned to 7b76e69cf9)
Solutions
- Set TKey to match the column's DataType exactly (check df[columnName].DataType).
- If types differ, first convert the column to the desired type (e.g. build a new PrimitiveDataFrameColumn<T> from converted values) and group on that.
- Guard with `df.GroupBy(columnName) is GroupBy<TKey>` before calling GroupBy<TKey>.
- Catch InvalidCastException and log column.DataType alongside the expected TKey to speed diagnosis.
Example fix
// before
var g = df.GroupBy<double>("Rating"); // Rating is actually int
// after
var g = df.GroupBy<int>("Rating"); // matches column DataType Defensive patterns
Strategy: type-guard
Validate before calling
Type colType = df[columnName].DataType;
if (colType != typeof(TKey))
throw new InvalidOperationException($"{columnName} is {colType}, expected {typeof(TKey)}"); Type guard
bool IsGroupableAs<T>(DataFrame df, string col) => df[col].DataType == typeof(T);
Try / catch
try { g = df.GroupBy<TKey>(columnName); }
catch (InvalidCastException ex) { logger.LogError(ex, "{0}: {1} vs {2}", columnName, df[columnName].DataType, typeof(TKey)); throw; } Prevention
- Check column.DataType before choosing the TKey generic parameter
- Convert columns to the desired type before grouping, not inside GroupBy
- Lock the CSV/parse schema so column types are stable across runs
When it happens
Trigger: df.GroupBy<int>("Date") where the Date column is DateTime or string; grouping a string column with GroupBy<double>; any TKey differing from column.DataType.
Common situations: Inferring column types from CSV where a column was read as string but assumed numeric; schema changes after a file format update; copying grouping code between DataFrames with different schemas.
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
- Column '{0}' does not exist
- Expected value to be of type {0}
- 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/4964056e778b2551.
Report an issue: GitHub.