dotnet/wpf · error · XamlParseException

SR.MalformedBracketCharacters

Error message

SR.MalformedBracketCharacters

What it means

At the end of a markup-extension string, MeScanner checks the bracket stack kept in CurrentBracketModeParseParameters. If closing bracket characters remain unmatched (BracketCharacterStack.Count > 0) when the extension terminates, it throws XamlParseException formatted with SR.MalformedBracketCharacters and the leftover character. It guarantees extension boundaries do not silently absorb unbalanced brackets.

Solutions

  1. Add the missing closing bracket reported in the message inside the extension value.
  2. Escape literal brackets/braces by prefixing the value with {} when the content is not a real extension.
  3. Store literal bracket-heavy text in a resource file instead of an inline markup extension.
  4. Validate with a minimal XamlReader.Load snippet to locate the attribute and character.

Example fix

<!-- before -->
<TextBlock Text="{StaticResource [Key}" />

<!-- after -->
<TextBlock Text="{StaticResource Key}" />
Defensive patterns

Strategy: validation

Validate before calling

static bool NoUnmatchedBrackets(string value) { var stack = new Stack<char>(); foreach (var c in value) { if (c=='('||c=='[') stack.Push(c); else if (c==')') { if (stack.Pop()!='(') return false; } else if (c==']') { if (stack.Pop()!='[') return false; } } return stack.Count==0; }

Try / catch

try { return XamlReader.Parse(xaml); } catch (XamlParseException ex) { return FallbackValue; }

Prevention

When it happens

Trigger: XAML where an extension value opens a bracket that never closes before the extension ends, e.g. `Text="{StaticResource [Key}"` or `Text="{Binding Path=(Foo.Bar}"`.

Common situations: Values containing literal '[' or '(' pasted into markup extensions unescaped; code that programmatically assembles extension strings dropping a closer; WPF designer round-trips of hand-edited markup.

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/4b662bf0ea661734. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/Parser/MeScanner.cs:497

                            bracketCharacterStack.Push(ch);
                            _context.CurrentBracketModeParseParameters.IsBracketEscapeMode = true;
                        }

                        sb.Append(ch);
                        break;
                    }

                    if (done)
                    {
                        if (braceCount > 0)
                        {
                            throw new XamlParseException(this, SR.UnexpectedTokenAfterME);
                        }
                        else
                        {
                            if (_context.CurrentBracketModeParseParameters?.BracketCharacterStack.Count > 0)
                            {
                                throw new XamlParseException(this, SR.Format(SR.MalformedBracketCharacters, ch.ToString()));
                            }
                        }

                        PushBack();
                        break;  // we are done.
                    }
                }

                atStart = false;
                Advance();
            }

            if (quoteChar != NullChar)
            {
                throw new XamlParseException(this, SR.UnclosedQuote);
            }

            string result = sb.ToString();

View on GitHub (pinned to 81131a70a4)