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

  1. Validate before calling: if (idx < 0 || idx >= df.Columns.Count) handle/throw.
  2. Prefer the string-based GroupBy(columnName) overload to avoid ordinal mistakes.
  3. Look up the ordinal via df.Columns.IndexOf(name) right before grouping.
  4. 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

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


AI-assisted analysis of dotnet/machinelearning@7b76e69cf9 (2026-09-11). Data as JSON: /api/errors/818fa18811752d15. Report an issue: GitHub.