dotnet/wpf · error · XamlParseException

SR.WhitespaceAfterME

Error message

SR.WhitespaceAfterME

What it means

MePullParser.Parse rejects a markup extension that has trailing whitespace after its terminating token, throwing XamlParseException(SR.WhitespaceAfterME). This strictness prevents ambiguous or unintended values like '{Binding Path} '.

Solutions

  1. Trim the markup-extension string before assigning/parsing
  2. Rewrite the attribute value so '}' is the last character
  3. Use string.Trim() on dynamically composed values

Example fix

// before
value = "{StaticResource Foo} ";
// after
value = "{StaticResource Foo}".Trim();
Defensive patterns

Strategy: validation

Validate before calling

string Sanitize(string s) => s?.Trim();
bool HasTrailingWs(string s) => s != null && s.Length > 0 && char.IsWhiteSpace(s[s.Length-1]);

Try / catch

try { nodes = parser.Parse(meString.Trim()); }
catch (XamlParseException ex) when (ex.Message.Contains("whitespace")) { /* normalize the source string */ }

Prevention

When it happens

Trigger: Markup-extension attribute values containing whitespace after the closing '}', e.g. ' {Binding Path} ' or '{StaticResource Foo} '.

Common situations: Whitespace introduced by XML formatting, template value strings with surrounding spaces, programmatic string concatenation appending a newline.

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/5519e06a77da94f7. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/Parser/MePullParser.cs:78

            {
                yield return node;
            }

            if (!f.found)
            {
                string brokenRule = _brokenRule;
                _brokenRule = null;
                throw new XamlParseException(_tokenizer, brokenRule);
            }

            if (_tokenizer.Token != MeTokenType.None)
            {
                throw new XamlParseException(_tokenizer, SR.UnexpectedTokenAfterME);
            }

            if (_tokenizer.HasTrailingWhitespace)
            {
                throw new XamlParseException(_tokenizer, SR.WhitespaceAfterME);
            }
        }

        private void SetBrokenRuleString(string ruleString)
        {
            if (string.IsNullOrEmpty(_brokenRule))
            {
                _brokenRule = SR.Format(SR.UnexpectedToken,
                                            _tokenizer.Token, ruleString, _originalText);
            }
        }

        private bool Expect(MeTokenType token, string ruleString)
        {
            if (_tokenizer.Token != token)
            {
                SetBrokenRuleString(ruleString);
                return false;

View on GitHub (pinned to 81131a70a4)