dotnet/machinelearning · error · ArgumentException
nameof(groupByColumnIndex)
Error message
nameof(groupByColumnIndex)
What it means
The GroupBy constructor validates that groupByColumnIndex lies within the DataFrame's columns: if dataFrame.Columns.Count < groupByColumnIndex or the index is negative, it throws ArgumentException(nameof(groupByColumnIndex)). Note the check uses '<' not '<=', so an index exactly equal to Columns.Count slips through here and fails later — treat any index >= Count as invalid.
Source
Thrown at src/Microsoft.Data.Analysis/GroupBy.cs:111
return _rows.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _rows.GetEnumerator();
}
}
#endregion
private readonly int _groupByColumnIndex;
private readonly IDictionary<TKey, ICollection<long>> _keyToRowIndicesMap;
private readonly DataFrame _dataFrame;
public GroupBy(DataFrame dataFrame, int groupByColumnIndex, IDictionary<TKey, ICollection<long>> keyToRowIndices)
{
if (dataFrame.Columns.Count < groupByColumnIndex || groupByColumnIndex < 0)
throw new ArgumentException(nameof(groupByColumnIndex));
_groupByColumnIndex = groupByColumnIndex;
_keyToRowIndicesMap = keyToRowIndices ?? throw new ArgumentException(nameof(keyToRowIndices));
_dataFrame = dataFrame;
}
private delegate void ColumnDelegate(int columnIndex, long rowIndex, ICollection<long> rows, TKey key, bool firstGroup);
private delegate void GroupByColumnDelegate(long rowNumber, TKey key);
private void EnumerateColumnsWithRows(GroupByColumnDelegate groupByColumnDelegate, ColumnDelegate columnDelegate, params string[] columnNames)
{
long rowNumber = 0;
bool firstGroup = true;
foreach (KeyValuePair<TKey, ICollection<long>> pairs in _keyToRowIndicesMap)
{
groupByColumnDelegate(rowNumber, pairs.Key);
ICollection<long> rows = pairs.Value;
IEnumerable<string> columns = columnNames;
if (columnNames == null || columnNames.Length == 0)
columns = _dataFrame.GetColumnNames();View on GitHub (pinned to 7b76e69cf9)
Solutions
- Validate before calling: if (idx < 0 || idx >= df.Columns.Count) handle/throw.
- Prefer the string-based GroupBy(columnName) overload to avoid ordinal mistakes.
- Look up the ordinal via df.Columns.IndexOf(name) right before grouping.
- Fix off-by-one: the maximum valid index is df.Columns.Count - 1.
Example fix
// before
df.GroupBy(df.Columns.Count); // invalid
// after
int idx = df.Columns.IndexOf("Key");
if (idx < 0 || idx >= df.Columns.Count)
throw new ArgumentOutOfRangeException(nameof(idx));
df.GroupBy(idx); Defensive patterns
Strategy: validation
Validate before calling
if (idx < 0 || idx >= df.Columns.Count)
throw new ArgumentOutOfRangeException(nameof(idx), $"Column index {idx} out of 0..{df.Columns.Count - 1}"); Type guard
bool isValidColumnIndex(DataFrame df, int idx) => idx >= 0 && idx < df.Columns.Count;
Try / catch
try { var gb = df.GroupBy(idx); }
catch (ArgumentException ex) when (ex.Message.Contains("groupByColumnIndex"))
{ /* invalid column ordinal: resolve by name */ } Prevention
- Group by column name, not ordinal, when possible.
- Resolve ordinals with df.Columns.IndexOf(name) at call time.
- Recompute ordinals after any schema change.
- Remember the max valid index is Columns.Count - 1.
When it happens
Trigger: Calling df.GroupBy(keyColumnIndex) with an index >= df.Columns.Count or a negative index, e.g. a hardcoded constant or a stale ordinal after columns were dropped.
Common situations: Hardcoded column positions broken by schema changes; computing the index from user input; off-by-one assuming the last ordinal (Count) is valid.
Related errors
- Column '{0}' does not exist
- Value name '{0}' matches an existing column name
- {0} and {1} must be different
- string.Format(Strings.DuplicateColumnName, column.Name)
- Strings.DuplicateColumnName (formatted with column.Name)
AI-assisted analysis of dotnet/machinelearning@7b76e69cf9 (2026-09-11).
Data as JSON: /api/errors/818fa18811752d15.
Report an issue: GitHub.