dotnet/wpf · error · InvalidOperationException

Bracket characters cannot be one of the following: '=' …

Error message

Bracket characters cannot be one of the following: '=' , ',', '\'', '\"', '{ ', ' }', '\\'

What it means

IsValidBracketCharacter throws when either bracket character belongs to the restricted character set. The characters '=', ',', single quote, double quote, '{', '}', and backslash are already structurally significant in XAML markup, so allowing them as custom brackets would break parsing.

Solutions

  1. Choose delimiter characters outside the restricted set, such as '[', ']', '<', '>', '|', or '#'
  2. Remove any attempt to re-register '{' and '}' — they are already handled natively
  3. Pre-screen the pair against the string "=,'\"{}\\" before adding

Example fix

// before
parser.AddBracketCharacters('{', '}');
// after
parser.AddBracketCharacters('[', ']');
Defensive patterns

Strategy: validation

Validate before calling

const string Restricted = "=,'\"{}\\";
bool IsAllowed(char c) => !Restricted.Contains(c);

Try / catch

try { tokenize(map); }
catch (InvalidOperationException ex) when (ex.Message.Contains("one of the following")) { /* replace reserved chars in map */ }

Prevention

When it happens

Trigger: Tokenize encounters a bracket dictionary containing any of: '=', ',', '\'', '"', '{', '}', '\\' as either the opening or closing character — e.g. trying to override or reuse '{' '}' as custom brackets.

Common situations: Developers attempting to redefine or augment the built-in curly-brace markup extension syntax, or building a delimiter scheme around quote/comma characters that XAML already reserves.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/8f4fc8bbdea8ba6c. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/Shared/MS/Internal/Xaml/Parser/SpecialBracketCharacters.cs:84

                        _endCharactersStringBuilder.Append(closingBracket);
                    }
                }
            }
        }

        private bool IsValidBracketCharacter(char openingBracket, char closingBracket)
        {
            if (openingBracket == closingBracket)
            {
                throw new InvalidOperationException("Opening bracket character cannot be the same as closing bracket character.");
            }
            else if (char.IsLetterOrDigit(openingBracket) || char.IsLetterOrDigit(closingBracket) || char.IsWhiteSpace(openingBracket) || char.IsWhiteSpace(closingBracket))
            {
                throw new InvalidOperationException("Bracket characters cannot be alpha-numeric or whitespace.");
            }
            else if (_restrictedCharSet.Contains(openingBracket) || _restrictedCharSet.Contains(closingBracket))
            {
                throw new InvalidOperationException("Bracket characters cannot be one of the following: '=' , ',', '\'', '\"', '{ ', ' }', '\\'");
            }
            else
            {
                return true;
            }
        }

        internal bool IsSpecialCharacter(char ch)
        {
            return _startChars.Contains(ch.ToString()) || _endChars.Contains(ch.ToString());
        }

        internal bool StartsEscapeSequence(char ch)
        {
            return _startChars.Contains(ch.ToString());
        }

        internal bool EndsEscapeSequence(char ch)

View on GitHub (pinned to 81131a70a4)