dotnet/wpf · error · XamlParseException
SR.UnexpectedTokenAfterME
Error message
SR.UnexpectedTokenAfterME
What it means
When MeScanner.ReadString reaches the end of a markup-extension value with braceCount still greater than zero (an unclosed '{' nested inside), it throws XamlParseException with SR.UnexpectedTokenAfterME. The scanner treats the extension as finished but leftover open braces mean extra/unclosed tokens follow the markup extension. System.Xaml throws this to fail fast on structurally incomplete `{}` expressions.
Solutions
- Count and close all nested braces: every '{' inside the extension value needs its own '}'.
- Simplify by removing nesting — compute the inner value as a resource and reference it once.
- Use an XAML-aware editor/IDE to validate brace balance before Load.
- Isolate the failing attribute by loading a minimal XAML fragment and inspect brace counts.
Example fix
<!-- before -->
<TextBlock Text="{Binding Path={x:Static sys:Foo.Bar}" />
<!-- after -->
<TextBlock Text="{Binding Path={x:Static sys:Foo.Bar}}" /> Defensive patterns
Strategy: validation
Validate before calling
static bool BracesBalanced(string value) { int depth = 0; foreach (var c in value) { if (c=='{') depth++; else if (c=='}') depth--; if (depth<0) return false; } return depth==0; } Try / catch
try { return XamlReader.Parse(xaml); } catch (XamlParseException ex) { Report(ex.Message, ex.LineNumber); return null; } Prevention
- Count braces when nesting markup extensions
- Prefer one-level extensions referencing pre-computed resources
- Lint generated XAML for brace balance
When it happens
Trigger: XAML like `Text="{Binding Path={x:Static sys:Foo.Bar"` — nested extensions not fully closed, or an inner '{' opened and the outer '}' reached first; e.g. `{StaticResource {x:Static Key` missing the inner closing brace(s).
Common situations: Nested markup extensions ({Binding {x:Static ...}}) hand-edited so one closing brace was deleted; template generators emitting partial extension strings; truncation when building XAML with string concatenation.
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
- brokenRule (SR.UnexpectedToken-based parser rule error)
- SR.InvalidClosingBracketCharacers
- SR.MalformedBracketCharacters
- SR.MalformedPropertyName
- SR.QuoteCharactersOutOfPlace
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/a51a619efb9d986a.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/Parser/MeScanner.cs:491
default: // All other character (including whitespace)
if (_currentSpecialBracketCharacters is not null && _currentSpecialBracketCharacters.StartsEscapeSequence(ch))
{
Stack<char> bracketCharacterStack =
_context.CurrentBracketModeParseParameters.BracketCharacterStack;
bracketCharacterStack.Clear();
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();
}
View on GitHub (pinned to 81131a70a4)