{"record":{"id":"6096bb28eb33bc7b","repo":"dotnet/wpf","slug":"sr-invalidclosingbracketcharacers","errorCode":null,"errorMessage":"SR.InvalidClosingBracketCharacers","messagePattern":"SR\\.InvalidClosingBracketCharacers","errorType":"exception","errorClass":"XamlParseException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/Parser/MeScanner.cs","lineNumber":400,"sourceCode":"\n                // If we are inside of MarkupExtensionBracketCharacters for a particular property or position parameter,\n                // scoop up everything inside one by one, and keep track of nested Bracket Characters in the stack.\n                else if (_context.CurrentBracketModeParseParameters is not null && _context.CurrentBracketModeParseParameters.IsBracketEscapeMode)\n                {\n                    Stack<char> bracketCharacterStack = _context.CurrentBracketModeParseParameters.BracketCharacterStack;\n                    if (_currentSpecialBracketCharacters.StartsEscapeSequence(ch))\n                    {\n                        bracketCharacterStack.Push(ch);\n                    }\n                    else if (_currentSpecialBracketCharacters.EndsEscapeSequence(ch))\n                    {\n                        if (_currentSpecialBracketCharacters.Match(bracketCharacterStack.Peek(), ch))\n                        {\n                            bracketCharacterStack.Pop();\n                        }\n                        else\n                        {\n                            throw new XamlParseException(this, SR.Format(SR.InvalidClosingBracketCharacers, ch.ToString()));\n                        }\n                    }\n                    else if (ch == Backslash)\n                    {\n                        escaped = true;\n                    }\n\n                    if (bracketCharacterStack.Count == 0)\n                    {\n                        _context.CurrentBracketModeParseParameters.IsBracketEscapeMode = false;\n                    }\n\n                    if (!escaped)\n                    {\n                        sb.Append(ch);\n                    }\n                }\n                else","sourceCodeStart":382,"sourceCodeEnd":418,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/Parser/MeScanner.cs#L382-L418","documentation":"MeScanner.ReadString tracks a stack of open bracket characters inside a markup-extension string. When a closing bracket arrives (e.g. ')' or ']') that does not match the bracket currently on top of the stack, the scanner throws XamlParseException with SR.InvalidClosingBracketCharacers, naming the offending character. This keeps brace/bracket nesting inside `{}` values unambiguous so System.Xaml can tell extension boundaries from literal text.","triggerScenarios":"Parsing XAML where a markup extension string contains a closing bracket without its matching opener, e.g. `Text=\"{StaticResource Key)]}\"` or nested `{x:Static Member=...)}` where a ')' appears with only '[' opened.","commonSituations":"Copy-pasted XAML where literal ')' text was not escaped; template or code-generated markup with mismatched bracket pairs; values like regular expressions or format strings containing brackets pasted into markup extensions unescaped.","solutions":["Balance the brackets in the value so every closer matches the most recently opened bracket.","Escape literal braces with a leading {} sequence if the text is not meant to be a markup extension.","Move bracket-heavy literal values into a resource (resx/ResourceDictionary) and reference them, avoiding inline parsing.","Check the reported character and its position in the attribute value; remove or escape the stray closer."],"exampleFix":"<!-- before -->\n<TextBox Text=\"{StaticResource Pattern)]}\" />\n\n<!-- after -->\n<TextBox Text=\"{StaticResource Pattern}\" />","handlingStrategy":"validation","validationCode":"static bool BracketsBalanced(string value) { int depth = 0; foreach (var c in value) { if (c=='('||c=='[') depth++; if (c==')'||c==']') depth--; if (depth<0) return false; } return depth==0; }","typeGuard":null,"tryCatchPattern":"try { return XamlReader.Parse(xaml); } catch (XamlParseException ex) when (ex.Message.Contains(\"bracket\")) { return null; }","preventionTips":["Validate bracket balance of attribute values before Load","Escape literal brackets or move them into resources","Use round-trip designer output rather than manual edits"],"tags":["xaml","markup-extension","bracket-mismatch","parser"],"backgroundTag":"invalid-argument-format","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}