dotnet/wpf · error · ArgumentException

SR.GlyphsCaretStopsLengthCorrespondsToUnicodeString

Error message

SR.GlyphsCaretStopsLengthCorrespondsToUnicodeString

What it means

ParseCaretStops walks the hex digit string four caret stops per nibble; when a set bit indicates a caret stop for a code point index beyond the UnicodeString length, the caret-stop spec is longer than allowed and this ArgumentException is thrown.

Solutions

  1. Shorten the CaretStops string so it covers at most the UnicodeString code-point count
  2. Regenerate CaretStops from the current UnicodeString
  3. If caret stops are not needed, clear CaretStops entirely

Example fix

// before
UnicodeString="abc" CaretStops="FFFFFFFF"
// after
UnicodeString="abc" CaretStops="F0"
Defensive patterns

Strategy: validation

Validate before calling

int codePoints = unicodeString.OfType<char>().Count(c => !char.IsSurrogate(c) || char.IsHighSurrogate(c));
int maxBits = caretStops.Length * 4;
bool ok = maxBits <= codePoints;

Try / catch

try { glyphs.CaretStops = stops; } catch (ArgumentException) { /* regenerate stops from current string */ }

Prevention

When it happens

Trigger: CaretStops string whose decoded bit count exceeds the number of code points in Glyphs.UnicodeString — e.g. long CaretStops paired with a short UnicodeString.

Common situations: Changing UnicodeString to a shorter text but leaving the old CaretStops value in place in XAML; copying CaretStops between Glyphs elements with different string lengths.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/Glyphs.cs:255

                    continue;

                int nibble;

                if ('0' <= c && c <= '9')
                    nibble = c - '0';
                else if ('a' <= c && c <= 'f')
                    nibble = c - 'a' + 10;
                else if ('A' <= c && c <= 'F')
                    nibble = c - 'A' + 10;
                else
                    throw new ArgumentException(SR.GlyphsCaretStopsContainsHexDigits, "CaretStops");

                Debug.Assert(0 <= nibble && nibble <= 15);

                if ((nibble & 8) != 0)
                {
                    if (i >= caretStops.Length)
                        throw new ArgumentException(SR.GlyphsCaretStopsLengthCorrespondsToUnicodeString, "CaretStops");
                    caretStops[i] = true;
                }
                ++i;
                if ((nibble & 4) != 0)
                {
                    if (i >= caretStops.Length)
                        throw new ArgumentException(SR.GlyphsCaretStopsLengthCorrespondsToUnicodeString, "CaretStops");
                    caretStops[i] = true;
                }
                ++i;
                if ((nibble & 2) != 0)
                {
                    if (i >= caretStops.Length)
                        throw new ArgumentException(SR.GlyphsCaretStopsLengthCorrespondsToUnicodeString, "CaretStops");
                    caretStops[i] = true;
                }
                ++i;
                if ((nibble & 1) != 0)

View on GitHub (pinned to 81131a70a4)