dotnet/wpf · error · ArgumentException
SR.GlyphsClusterBadCharactersBeforeBracket
Error message
SR.GlyphsClusterBadCharactersBeforeBracket
What it means
Glyph index specs support cluster syntax '(a,b,c)' inside the Indices string. ParseGlyphsProperty's ReadGlyphIndex requires that only whitespace precede the opening '(' of a cluster; any other character before it throws this ArgumentException.
Solutions
- Insert a separator (e.g. ';') or space between the preceding glyph index and the cluster bracket
- Ensure cluster groups like '(a,b)' start at the beginning of the spec or after valid separators
- Validate the Indices string against the Glyphs cluster grammar
Example fix
// before Indices="12(3,4)" // after Indices="12;(3,4)"
Defensive patterns
Strategy: validation
Validate before calling
int i = indices.IndexOf('(');
bool ok = i <= 0 || indices.Take(i).All(char.IsWhiteSpace); Try / catch
try { glyphs.Indices = value; } catch (ArgumentException) { /* insert ';' separator before '(' */ } Prevention
- Separate cluster groups with ';' or whitespace
- Follow the Glyphs.Indices grammar when generating strings
- Test index strings through ParseGlyphsProperty before use
When it happens
Trigger: An Indices value where a cluster opening bracket follows a non-whitespace character, e.g. '12(3,4)' or 'a(1,2)'.
Common situations: Hand-written Indices strings missing the semicolon or comma separator before a cluster; converter output concatenating glyph indexes and clusters without a separator.
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
- SR.GlyphsClusterNoNestedClusters
- Collection_BadRank
- SR.GlyphsAdvanceWidthCannotBeNegative
- SR.GlyphsCaretStopsContainsHexDigits
- SR.GlyphsCaretStopsLengthCorrespondsToUnicodeString
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/52654181cb74e5fd.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/Glyphs.cs:407
/// <returns>true if glyph index is present, false if glyph index is not present.</returns>
private bool ReadGlyphIndex(
ReadOnlySpan<char> valueSpec,
ref bool inCluster,
ref int glyphClusterSize,
ref int characterClusterSize,
ref ushort glyphIndex)
{
// the format is ... [(CharacterClusterSize[:GlyphClusterSize])] GlyphIndex ...
ReadOnlySpan<char> glyphIndexString = valueSpec;
int firstBracket = valueSpec.IndexOf('(');
if (firstBracket != -1)
{
// Only spaces are allowed before the bracket
for (int i=0; i<firstBracket; i++)
{
if (!Char.IsWhiteSpace(valueSpec[i]))
throw new ArgumentException(SR.GlyphsClusterBadCharactersBeforeBracket);
}
if (inCluster)
throw new ArgumentException(SR.GlyphsClusterNoNestedClusters);
int secondBracket = valueSpec.IndexOf(')');
if (secondBracket == -1 || secondBracket <= firstBracket + 1)
throw new ArgumentException(SR.GlyphsClusterNoMatchingBracket);
// look for colon separator
int colon = valueSpec.IndexOf(':');
if (colon == -1)
{
// parse glyph cluster size
ReadOnlySpan<char> characterClusterSpec = valueSpec.Slice(firstBracket + 1, secondBracket - (firstBracket + 1));
characterClusterSize = int.Parse(characterClusterSpec, provider: CultureInfo.InvariantCulture);
glyphClusterSize = 1;
}View on GitHub (pinned to 81131a70a4)