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

  1. Count and close all nested braces: every '{' inside the extension value needs its own '}'.
  2. Simplify by removing nesting — compute the inner value as a resource and reference it once.
  3. Use an XAML-aware editor/IDE to validate brace balance before Load.
  4. 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

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


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)