dotnet/wpf · error · ArgumentException

SR.Argument_InvalidOffLen

Error message

SR.Argument_InvalidOffLen

What it means

RBTree<T>.CopyTo validates the destination array arguments via ArgumentNullException.ThrowIfNull, ThrowIfNegative(arrayIndex), and throws ArgumentException(SR.Argument_InvalidOffLen) when arrayIndex + Count exceeds array.Length — i.e. the array is too small to hold all tree elements at the given offset.

Solutions

  1. Allocate the array with size tree.Count + arrayIndex before copying
  2. Pass arrayIndex 0 when using a fresh array of length Count
  3. Copy to a List<T> via constructor if the size is unknown

Example fix

// before
var arr = new string[count]; // count from an earlier snapshot
tree.CopyTo(arr, 1); // too small
// after
var arr = new string[tree.Count];
tree.CopyTo(arr, 0);
Defensive patterns

Strategy: validation

Validate before calling

if (array == null) throw new ArgumentNullException(nameof(array));
if (arrayIndex < 0 || tree.Count > array.Length - arrayIndex)
    throw new ArgumentException("Destination array too small for given arrayIndex", nameof(array));

Try / catch

try { tree.CopyTo(arr, idx); }
catch (ArgumentException) { arr = new T[tree.Count]; tree.CopyTo(arr, 0); }

Prevention

When it happens

Trigger: Calling rbTree.CopyTo(array, index) where array.Length - index < tree.Count (e.g. copying an empty-initialized array, or using index > 0 without sizing the array accordingly).

Common situations: Pre-sizing arrays from a stale Count, copying into arrays reused across refreshes, off-by-one when index is non-zero.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Data/RBTree.cs:570

        public void Clear()
        {
            LeftChild = null;
            LeftSize = 0;
        }

        public bool Contains(T item)
        {
            RBFinger<T> finger = Find(item, Comparison);
            return finger.Found;
        }

        public void CopyTo(T[] array, int arrayIndex)
        {
            ArgumentNullException.ThrowIfNull(array);
            ArgumentOutOfRangeException.ThrowIfNegative(arrayIndex);
            if (arrayIndex + Count > array.Length)
                throw new ArgumentException(SR.Argument_InvalidOffLen);

            foreach (T item in this)
            {
                array[arrayIndex] = item;
                ++arrayIndex;
            }
        }

        public int Count
        {
            get { return LeftSize; }
        }

        public bool IsReadOnly
        {
            get { return false; }
        }

View on GitHub (pinned to 81131a70a4)