dotnet/wpf · error · ArgumentOutOfRangeException

throw new ArgumentOutOfRangeException(nameof(index));

Error message

throw new ArgumentOutOfRangeException(nameof(index));

What it means

FrugalList's SingleItemList.Insert throws ArgumentOutOfRangeException when Insert is called with an index other than 0 on an empty/single-entry list. A frugal single-item list only ever holds one entry, so the only legal insert position is index 0 when _count is 0; any other index is out of range for the backing store.

Solutions

  1. Only insert at index 0 into a single-item frugal list
  2. Use Add instead of Insert for appending; the frugal list promotes capacity automatically
  3. Check that the index satisfies 0 <= index <= _count before calling Insert
  4. If multiple items are needed, upgrade to a larger FrugalList variant or a standard List<T>

Example fix

// before
list.Insert(list.Count + 1, item); // wrong index
// after
list.Insert(0, item); // or list.Add(item);
Defensive patterns

Strategy: validation

Validate before calling

if (index < 0 || index > list.Count) throw new ArgumentOutOfRangeException(nameof(index));

Try / catch

try { list.Insert(index, item); }
catch (ArgumentOutOfRangeException) { list.Add(item); // fall back to append
}

Prevention

When it happens

Trigger: Calling Insert(index, value) with index != 0 on a SingleItemList (count 0 or 1), e.g. Insert(1, item) on a fresh list, or Insert at the end position when count is already 1.

Common situations: Generic code written against IList that appends with Insert(Count, item) — for a single-item list Count may be 0 and Insert(0,...) works, but code that assumes larger capacity and computes indices from a stale count will land here.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/Shared/MS/Utility/FrugalList.cs:285

            if (EqualityComparer<T>.Default.Equals(_loneEntry, value))
            {
                return 0;
            }

            return -1;
        }

        public override void Insert(int index, T value)
        {
            // Should only get here if count and index are 0
            if ((_count < SIZE) && (index < SIZE))
            {
                _loneEntry = value;
                ++_count;
                return;
            }

            throw new ArgumentOutOfRangeException(nameof(index));
        }

        public override void SetAt(int index, T value)
        {
            // Overwrite item at index
            _loneEntry = value;
        }

        public override bool Remove(T value)
        {
            // Wipe out the info in the only entry if it matches the item.
            if (EqualityComparer<T>.Default.Equals(_loneEntry, value))
            {
                _loneEntry = default(T);
                --_count;
                return true;
            }

View on GitHub (pinned to 81131a70a4)