dotnet/wpf · error · ArgumentOutOfRangeException

SR.TableCollectionOutOfRange

Error message

SR.TableCollectionOutOfRange

What it means

TableColumnCollectionInternal.Insert validates the insertion index against the collection bounds before inserting a TableColumn. An index below 0 or greater than Size (current count) throws ArgumentOutOfRangeException(SR.TableCollectionOutOfRange). The guard ensures the Table's column collection stays contiguous.

Solutions

  1. Clamp the index to [0, Count] before calling Insert
  2. Use Add() instead of Insert() when appending a column
  3. Re-read the collection Count immediately before inserting rather than caching it
  4. For -1 sentinel values from selection UI, convert them to Count or skip the insert

Example fix

// before
columns.Insert(selectedIndex, newColumn);
// after
int idx = Math.Max(0, Math.Min(selectedIndex, columns.Count));
columns.Insert(idx, newColumn);
Defensive patterns

Strategy: validation

Validate before calling

bool canInsert = index >= 0 && index <= columns.Count;

Try / catch

try { columns.Insert(index, col); } catch (ArgumentOutOfRangeException) { columns.Add(col); }

Prevention

When it happens

Trigger: Calling Insert with index < 0 or index > Count on a TableColumnCollection (e.g. inserting at Count+1 to 'append').

Common situations: Computing the insertion index from a loop or saved value that has become stale after prior removals; off-by-one when intending to append (append should use index == Count or Add); UI-driven index values that are -1 (e.g. 'no selection').

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/dcf168c2ea21695d. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/documents/TableColumnCollectionInternal.cs:99

        /// </exception>
        /// <remarks>
        /// If Count already equals Capacity, the capacity of the
        /// ContentElementCollection is increased before the new TItem is inserted.
        ///
        /// If index is equal to Count, TItem is added to the
        /// end of ContentElementCollection.
        ///
        /// The TItems that follow the insertion point move down to
        /// accommodate the new TItem. The indexes of the TItems that are
        /// moved are also updated.
        /// </remarks>
        public override void Insert(int index, TableColumn item)
        {
            Version++;

            if (index < 0 || index > Size)
            {
                throw new ArgumentOutOfRangeException(SR.TableCollectionOutOfRange);
            }
            ArgumentNullException.ThrowIfNull(item);
            if (Size == Items.Length)
            {
                EnsureCapacity(Size + 1);
            }

            for (int i = Size - 1; i >= index; --i)
            {
                Debug.Assert(BelongsToOwner(Items[i]));

                Items[i + 1] = Items[i];
                Items[i].Index = i + 1;
            }

            Items[index] = null;

            Size++;

View on GitHub (pinned to 81131a70a4)