dotnet/wpf · error · ArgumentException

SR.Format(SR.Collection_BadDestArray, this.GetType().Name)

Error message

SR.Format(SR.Collection_BadDestArray, this.GetType().Name)

What it means

FreezableCollection<T>.CopyTo throws ArgumentException (with InvalidCastException as inner) when the destination Array's element type cannot hold a T. The collection writes each item via Array.SetValue and converts any InvalidCastException into this ArgumentException, naming the collection type. It exists so that copying to an incompatible array fails with a clear message instead of a raw cast exception.

Solutions

  1. Allocate the destination array with element type exactly T (or a base type/interface T implements), e.g. new MyFreezable[collection.Count].
  2. Use the generic ICollection<T>.CopyTo or ToArray() instead of the non-generic ICollection.CopyTo.
  3. If the target type differs, copy via LINQ: collection.Cast<TargetType>().ToArray() after verifying convertibility.

Example fix

// before
Array dest = Array.CreateInstance(typeof(object), collection.Count);
collection.CopyTo(dest, 0);
// after
var dest = new MyItemType[collection.Count];
((ICollection<MyItemType>)collection).CopyTo(dest, 0);
Defensive patterns

Strategy: validation

Validate before calling

if (dest == null) throw new ArgumentNullException(nameof(dest));
if (dest.Rank != 1) throw new ArgumentException("dest must be a 1-D array");
if (dest.Length - index < collection.Count) throw new ArgumentException("dest too small");
// element type must be assignable from every T
if (!typeof(T).IsAssignableTo(dest.GetType().GetElementType())) throw new ArgumentException("dest element type incompatible");

Type guard

bool IsCompatibleDestArray(Array a) => a != null && a.Rank == 1 && typeof(T).IsAssignableTo(a.GetType().GetElementType());

Try / catch

try { collection.CopyTo(dest, 0); }
catch (ArgumentException ex) when (ex.InnerException is InvalidCastException) { /* reallocate as T[] and retry */ }

Prevention

When it happens

Trigger: Calling CopyTo with an array whose element type is not T or a supertype of T, e.g. freezing/casting a FreezableCollection<Rect> and copying into an object[] that later fails on SetValue, or copying into an array of an unrelated type (int[], string[]).

Common situations: Legacy non-generic ICollection.CopyTo calls, data-binding or serialization code that allocates Array.CreateInstance with the wrong type, refactoring that changed T but not the consuming CopyTo call site.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/FreezableCollection.cs:496

            if (array.Rank != 1)
            {
                throw new ArgumentException(SR.Collection_BadRank);
            }

            // Elsewhere in the collection we throw an AE when the type is
            // bad so we do it here as well to be consistent
            try
            {
                int count = _collection.Count;
                for (int i = 0; i < count; i++)
                {
                    array.SetValue(_collection[i], index + i);
                }
            }
            catch (InvalidCastException e)
            {
                throw new ArgumentException(SR.Format(SR.Collection_BadDestArray, this.GetType().Name), e);
            }
        }

        bool ICollection.IsSynchronized
        {
            get
            {
                ReadPreamble();

                return IsFrozen || Dispatcher != null;
            }
        }

        object ICollection.SyncRoot
        {
            get
            {
                ReadPreamble();

View on GitHub (pinned to 81131a70a4)