dotnet/wpf · error · ArgumentException

SR.TextElementCollection_NoEnumerator

Error message

SR.TextElementCollection_NoEnumerator

What it means

Thrown by TextElementCollection<T>.AddRange when GetEnumerator() on the supplied range returns null. AddRange requires an enumerable object that actually yields an IEnumerator to iterate and insert items.

Solutions

  1. Pass a standard collection implementing IEnumerable correctly (List<T>, array, etc.).
  2. Fix the custom type's GetEnumerator to return a valid non-null IEnumerator.
  3. If the source may be null-yielding, enumerate it into a List first and pass that to AddRange.

Example fix

// before
collection.AddRange(customEnumerable); // GetEnumerator() returns null
// after
collection.AddRange(customEnumerable.Cast<object>().ToList());
Defensive patterns

Strategy: validation

Validate before calling

var snapshot = range?.Cast<object>().ToList();
if (snapshot != null) collection.AddRange(snapshot);

Type guard

bool HasValidEnumerator(System.Collections.IEnumerable e) => e?.GetEnumerator() != null;

Try / catch

try { collection.AddRange(range); }
catch (ArgumentException ex) when (ex.ParamName == "range") { /* materialize range into a List<object> and retry */ }

Prevention

When it happens

Trigger: Calling AddRange(range) where range's GetEnumerator() returns null — typically a custom collection with a broken/returning-null GetEnumerator implementation, not a standard collection.

Common situations: Passing a hand-rolled enumerable whose GetEnumerator returns null; passing an object that only nominally implements IEnumerable.

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/92773a9495696ae7. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextElementCollection.cs:321

            {
                this.TextContainer.EndChange();
            }
        }

        /// <summary>
        /// Adds the elements of an IEnumerable to this collection.
        /// </summary>
        /// <param name="range">
        /// Elements to add.
        /// </param>
        public void AddRange(IEnumerable range)
        {
            ArgumentNullException.ThrowIfNull(range);

            IEnumerator enumerator = range.GetEnumerator();
            if (enumerator == null)
            {
                throw new ArgumentException(SR.TextElementCollection_NoEnumerator, nameof(range));
            }

            this.TextContainer.BeginChange();
            try
            {
                while (enumerator.MoveNext())
                {
                    TextElementType element = enumerator.Current as TextElementType;

                    if (element == null)
                    {
                        // REVIEW: It would be better design if we reviewed all elements in the range before starting an insert.
                        // Otherwise, we might insert half the elements and then throw.
                        throw new ArgumentException(SR.Format(SR.TextElementCollection_ItemHasUnexpectedType, "range", typeof(TextElementType).Name, typeof(TextElementType).Name), "value");
                    }

                    Add(element);
                }

View on GitHub (pinned to 81131a70a4)