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
- Add the missing closing bracket reported in the message inside the extension value.
- Escape literal brackets/braces by prefixing the value with {} when the content is not a real extension.
- Store literal bracket-heavy text in a resource file instead of an inline markup extension.
- 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
- Escape literal brackets with {} prefix when content is not an extension
- Match bracket kinds exactly '(' vs '['
- Keep bracket-heavy literals in resx files
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.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- SR.InvalidClosingBracketCharacers
- brokenRule (SR.UnexpectedToken-based parser rule error)
- SR.MalformedPropertyName
- SR.QuoteCharactersOutOfPlace
- SR.UnclosedQuote
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)