dotnet/wpf · error · ArgumentException
SR.GlyphsIndexRequiredIfNoUnicode
Error message
SR.GlyphsIndexRequiredIfNoUnicode
What it means
Thrown by Glyphs.ParseGlyphsProperty while filling glyph defaults with a 1:1 character-to-glyph mapping. When no explicit glyph index was parsed for a character, the code derives the glyph from the corresponding UnicodeString character — but if UnicodeString is null or empty there is nothing to derive from. The parser requires either explicit glyph indices or a non-empty UnicodeString.
Solutions
- Set Glyphs.UnicodeString (or Characters) to a non-empty string when GlyphIndices omits any explicit glyph index.
- Provide an explicit glyph index for every comma-separated slot in GlyphIndices.
- Remove trailing/empty ';,' slots from the GlyphIndices string.
Example fix
<!-- before --> <Glyphs GlyphIndices=";15;20" /> <!-- after --> <Glyphs GlyphIndices=";15;20" UnicodeString="abc" />
Defensive patterns
Strategy: validation
Validate before calling
bool hasEmptySlotsNeedingUnicode = glyphIndices.Split(';').Any(string.IsNullOrEmpty);
if (hasEmptySlotsNeedingUnicode && string.IsNullOrEmpty(glyphs.UnicodeString))
throw new InvalidOperationException("UnicodeString required when GlyphIndices omits explicit indices"); Type guard
static bool IndicesSelfContained(string indices) => indices.Split(';').Where(s => s.Length > 0).Count() == indices.Split(';').Count(s => s.Length == 0) ? false : true; // empty slots exist -> UnicodeString needed
// simpler: static bool NeedsUnicodeString(string indices) => indices != null && (indices.StartsWith(";") || indices.Contains(";;") || indices.EndsWith(";")); Try / catch
try { glyphs.GlyphIndices = indices; }
catch (ArgumentException ex) when (string.IsNullOrEmpty(glyphs.UnicodeString)) { glyphs.UnicodeString = fallbackText; glyphs.GlyphIndices = indices; } Prevention
- Set UnicodeString before GlyphIndices when using empty index slots
- Provide explicit indices for every glyph instead of empty slots
- Validate XAML Glyphs elements with a linter that flags Indices without UnicodeString
When it happens
Trigger: Assigning Glyphs.GlyphIndices (or UnicodeString) such that some positions lack explicit indices while Glyphs.UnicodeString is null or empty — e.g. GlyphIndices="" with trailing ';' items, or Indices-only usage without setting UnicodeString/Characters.
Common situations: XAML Glyphs element that sets only GlyphIndices and forgets UnicodeString; data-bound or computed Indices strings that end with separators producing empty value slots.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- SR.GlyphsClusterMisplacedSeparator
- SR.GlyphsClusterNoMatchingBracket
- SR.GlyphsIndexRequiredWithinCluster
- SR.GlyphsTooManyCommas
- MappingParseError(_scanner.Start, MappingScanner.Ident…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/7ada05588f8c39cc.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/Glyphs.cs:566
ReadOnlySpan<char> valueSpec = glyphsProp.AsSpan(valueStartIndex, len);
#region Interpret one comma-delimited value
switch (valueWithinGlyph)
{
case 0:
bool wasInCluster = inCluster;
// interpret cluster size and glyph index spec
if (!ReadGlyphIndex(
valueSpec,
ref inCluster,
ref glyphClusterSize,
ref characterClusterSize,
ref parsedGlyphData.glyphIndex))
{
if (String.IsNullOrEmpty(unicodeString))
throw new ArgumentException(SR.GlyphsIndexRequiredIfNoUnicode);
if (unicodeString.Length <= parsedCharacterCount)
throw new ArgumentException(SR.GlyphsUnicodeStringIsTooShort);
parsedGlyphData.glyphIndex = GetGlyphFromCharacter(fontFace, unicodeString[parsedCharacterCount]);
}
if (!wasInCluster && clusterMap != null)
{
// fill out cluster map at the start of each cluster
if (inCluster)
{
for (int ch = parsedCharacterCount; ch < parsedCharacterCount + characterClusterSize; ++ch)
{
SetClusterMapEntry(clusterMap, ch, (ushort)parsedGlyphCount);
}
}
elseView on GitHub (pinned to 81131a70a4)