dotnet/wpf · error · ArgumentException

SR.TableCollectionRangeOutOfRange

Error message

SR.TableCollectionRangeOutOfRange

What it means

RemoveRange validates that the requested range [index, index+count) lies inside the collection. If count is negative it throws ArgumentOutOfRangeException(TableCollectionCountNeedNonNegNum), and if Size - index < count the range extends past the end of the collection and it throws ArgumentException(TableCollectionRangeOutOfRange).

Solutions

  1. Recompute index and count immediately before calling RemoveRange against the current collection size.
  2. Clamp: var c = Math.Min(count, collection.Count - index); if (c > 0) collection.RemoveRange(index, c);
  3. Prefer removing items by reference (Remove(item)) or removing from the end of the collection backwards.
  4. Guard with if (index >= 0 && count >= 0 && index + count <= collection.Count) before the call.

Example fix

// before
collection.RemoveRange(startIndex, endIndex - startIndex + 1);
// after
if (startIndex >= 0 && endIndex < collection.Count)
    collection.RemoveRange(startIndex, endIndex - startIndex + 1);
Defensive patterns

Strategy: validation

Validate before calling

if (index < 0 || count < 0 || index + count > collection.Count)
    throw new ArgumentOutOfRangeException(nameof(index), "range outside collection");

Type guard

static bool CanRemoveRange<T>(TableTextElementCollectionInternal<T> c, int index, int count)
    => index >= 0 && count >= 0 && index <= c.Count && count <= c.Count - index;

Prevention

When it happens

Trigger: Calling TableTextElementCollectionInternal.RemoveRange(index, count) where index+count exceeds Size, e.g. computing count from stale indices or after items were already removed.

Common situations: Batch-removing TableRow/TableCell/Run elements while holding indexes captured before prior mutations; iterating and removing with an index that drifts as the collection shrinks.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/documents/TableTextElementCollectionInternal.cs:229

        /// The TItems that follow the removed TItems move up to occupy
        /// the vacated spot. The indices of the TItems that are moved are
        /// also updated.
        /// </remarks>
        public override void RemoveRange(int index, int count)
        {
            Version++;

            if (index < 0 || index >= Size)
            {
                throw new ArgumentOutOfRangeException(SR.TableCollectionOutOfRange);
            }
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException(SR.TableCollectionCountNeedNonNegNum);
            }
            if (Size - index < count)
            {
                throw new ArgumentException(SR.TableCollectionRangeOutOfRange);
            }

            if (count > 0)
            {
                for (int i = index + count - 1; i >= index; --i)
                {
                    Debug.Assert(BelongsToOwner(Items[i]));
                    Remove(Items[i]);
                }
            }
}

        /// <summary>
        /// Sets the specified TItem at the specified index;
        /// Connects the item to the model tree;
        /// Notifies the TItem about the event.
        /// </summary>
        /// <exception cref="ArgumentException">

View on GitHub (pinned to 81131a70a4)