dotnet/wpf · error · ArgumentException

SR.GlyphsUnicodeStringAndIndicesCannotBothBeEmpty

Error message

SR.GlyphsUnicodeStringAndIndicesCannotBothBeEmpty

What it means

When computing the GlyphRun for a Glyphs element, both UnicodeString and Indices being null or empty leaves nothing to render, so ParseGlyphRunProperties throws this ArgumentException during measure/layout.

Solutions

  1. Set either UnicodeString or Indices to a non-empty value before the element is measured
  2. If no glyphs are wanted, remove the Glyphs element instead of leaving both properties empty
  3. Ensure data bindings produce non-empty values before layout

Example fix

// before
<g:Glyphs FontUri="..." OriginX="0" OriginY="0" />
// after
<g:Glyphs FontUri="..." OriginX="0" OriginY="0" UnicodeString="Hello" />
Defensive patterns

Strategy: validation

Validate before calling

bool ok = !string.IsNullOrEmpty(glyphs.UnicodeString) || !string.IsNullOrEmpty(glyphs.Indices);
if (!ok) { /* set one or remove the element */ }

Try / catch

try { host.Measure(availableSize); } catch (ArgumentException) { /* Glyphs had no content; hide or populate */ }

Prevention

When it happens

Trigger: Creating a Glyphs element (in XAML or code) with neither UnicodeString nor Indices set, then measuring/rendering it; both properties set to empty strings.

Common situations: Data-bound Glyphs where the bound source returned an empty string; XAML templates where Glyphs properties are supplied later; default-constructed Glyphs added directly to a canvas.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

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

            // If the number of entries in the caret stop specification string is less than the number of code points,
            // set the remaining caret stop values to true.
            while (i < caretStops.Length)
            {
                caretStops[i++] = true;
            }
            glyphRunProperties.caretStops = caretStops;
        }

        private void ParseGlyphRunProperties()
        {
            LayoutDependentGlyphRunProperties glyphRunProperties = null;
            Uri uri = FontUri;

            if (uri != null)
            {
                // Indices and UnicodeString cannot both be empty.
                if (String.IsNullOrEmpty(UnicodeString) && String.IsNullOrEmpty(Indices))
                    throw new ArgumentException(SR.GlyphsUnicodeStringAndIndicesCannotBothBeEmpty);

                glyphRunProperties = new LayoutDependentGlyphRunProperties(GetDpi().PixelsPerDip);

                if (!uri.IsAbsoluteUri)
                {
                    uri = BindUriHelper.GetResolvedUri(BaseUriHelper.GetBaseUri(this), uri);
                }

                // Package-boundary guard. When this Glyphs element is loaded
                // inside an XPS package context, reject any FontUri that
                // escapes the package. This ensures that font resources
                // referenced within XPS documents remain contained within the
                // same package, consistent with the XPS specification.
                MS.Internal.XpsLoadingContext.EnforcePackageRelativeUri(BaseUriHelper.GetBaseUri(this), uri);
                glyphRunProperties.glyphTypeface = new GlyphTypeface(uri, StyleSimulations);

                glyphRunProperties.unicodeString = UnicodeString;
                glyphRunProperties.sideways = IsSideways;

View on GitHub (pinned to 81131a70a4)