dotnet/wpf · error · ArgumentException

SR.Arg_NonZeroLowerBound

Error message

SR.Arg_NonZeroLowerBound

What it means

CopyTo only supports zero-based arrays; the library throws ArgumentException with SR.Arg_NonZeroLowerBound when array.GetLowerBound(0) != 0. Non-zero-lower-bound arrays ( creatable via Array.CreateInstance with custom bounds) have no single correct mapping for the flat index parameter.

Solutions

  1. Use a standard zero-based array (new T[n] or Array.CreateInstance without lowerBounds)
  2. Copy into a zero-based array first, then Array.Copy into the custom-bounded array
  3. Guard with array.GetLowerBound(0) == 0 before calling

Example fix

// before
var arr = Array.CreateInstance(typeof(WeakReference), new[]{count}, new[]{1});
collection.CopyTo(arr, 0);
// after
var arr = new WeakReference[count];
collection.CopyTo(arr, 0);
Defensive patterns

Strategy: validation

Validate before calling

if (array.GetLowerBound(0) != 0) throw new ArgumentException("CopyTo requires a zero-based array.", nameof(array));

Type guard

bool IsZeroBased(Array a) => a.GetLowerBound(0) == 0;

Try / catch

try { ((ICollection)collection).CopyTo(array, index); } catch (ArgumentException) { var tmp = new T[collection.Count]; ((ICollection)collection).CopyTo(tmp, 0); Array.Copy(tmp, 0, array, index, tmp.Length); }

Prevention

When it happens

Trigger: Calling CopyTo passing an array created with Array.CreateInstance(typeof(WeakReference), lengths, lowerBounds) where the first lower bound is not 0.

Common situations: Interop with COM/legacy code that uses non-zero-based arrays; code ported from VB with Option Base-style arrays.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Collections/ObjectModel/WeakReadOnlyCollection.cs:146

                    {
                        System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
                    }
                }
                return _syncRoot;
            }
        }

        void ICollection.CopyTo(Array array, int index) {
            ArgumentNullException.ThrowIfNull(array);

            if (array.Rank != 1) {
                //ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
                throw new ArgumentException(SR.Arg_RankMultiDimNotSupported);
            }

            if( array.GetLowerBound(0) != 0 ) {
                //ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
                throw new ArgumentException(SR.Arg_NonZeroLowerBound);
            }

            if (index < 0) {
                //ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.arrayIndex, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
                throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_NeedNonNegNum);
            }

            if (array.Length - index < Count) {
                //ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
                throw new ArgumentException(SR.Arg_ArrayPlusOffTooSmall);
            }

            IList<T> dlist = CreateDereferencedList();
            if (array is T[] items)
            {
                dlist.CopyTo(items, index);
            }
            else

View on GitHub (pinned to 81131a70a4)