dotnet/wpf · error · NotSupportedException

NotSupportedException

Error message

NotSupportedException

What it means

The nested GlyphRun caret-stop list implementation (GlyphRun.CaretStopsList, an IList<bool> adapter over an internal BitArray) does not support IndexOf and throws NotSupportedException unconditionally. The adapter exists only to expose CaretStops for reading by index and enumerating.

Solutions

  1. Replace IndexOf with a manual for-loop over indices 0..Count-1 testing caretStops[i].
  2. Copy to an array or List<bool> (CopyTo/ToList) and call IndexOf on that.
  3. Prefer GlyphRun's caret APIs (GetNextCaretCharacterHit/GetPreviousCaretCharacterHit) which handle stop lookup internally.

Example fix

// before
int firstStop = run.CaretStops.IndexOf(true);
// after
int firstStop = -1;
for (int i = 0; i < run.CaretStops.Count; i++)
    if (run.CaretStops[i]) { firstStop = i; break; }
Defensive patterns

Strategy: type-guard

Validate before calling

int firstStop = -1;
for (int i = 0; i < caretStops.Count; i++) { if (caretStops[i]) { firstStop = i; break; } }

Type guard

bool SupportsIndexOf<T>(IList<T> list) => !(list.GetType().Name.Contains("CaretStopsList")) && list.GetType().GetMethod(nameof(IList<T>.IndexOf)) != null;

Try / catch

try { idx = caretStops.IndexOf(true); }
catch (NotSupportedException) { idx = Enumerable.Range(0, caretStops.Count).FirstOrDefault(i => caretStops[i], -1); }

Prevention

When it happens

Trigger: Calling caretStops.IndexOf(true/false) on GlyphRun.CaretStops, e.g. LINQ IndexOf or code searching for the first enabled caret stop.

Common situations: LINQ-heavy text editing code assuming any IList<bool> supports IndexOf; searching caret stops to find the nearest boundary instead of using GlyphRun's FindNearestCaretStop-based APIs.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/GlyphRun.cs:2093

        }


        /// <summary>
        /// This class implements behavior of a Boolean list that contains all true values.
        /// This allows us to have a single code path in hit testing API.
        /// </summary>
        private class DefaultCaretStopList : IList<bool>
        {
            public DefaultCaretStopList(int codePointCount)
            {
                _count = codePointCount + 1;
            }

            #region IList<bool> Members

            public int IndexOf(bool item)
            {
                throw new NotSupportedException();
            }

            public void Insert(int index, bool item)
            {
                throw new NotSupportedException();
            }

            public bool this[int index]
            {
                get
                {
                    return true;
                }
                set
                {
                    throw new NotSupportedException();
                }
            }

View on GitHub (pinned to 81131a70a4)