{"record":{"id":"926c9511528fc5e1","repo":"dotnet/wpf","slug":"sr-unmatchedloccomment","errorCode":null,"errorMessage":"SR.UnmatchedLocComment","messagePattern":"SR\\.UnmatchedLocComment","errorType":"exception","errorClass":"FormatException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Globalization/LocalizationComments.cs","lineNumber":192,"sourceCode":"                            // comment\n                            if (input[i] == EscapeChar && !escaped)\n                            {\n                                escaped = true;\n                            }\n                            else\n                            {\n                                tokenBuffer.Append(input[i]);\n                                escaped = false;\n                            }\n                        }\n                    }\n                }\n            }\n\n            if (currentPair.PropertyName != null || tokenBuffer.Length != 0)\n            {\n                // unmatched PropertyName and Value pair\n                throw new FormatException(SR.Format(SR.UnmatchedLocComment, input));\n            }\n\n            return tokens.ToArray();\n        }\n\n        //------------------------------\n        // Private methods\n        //------------------------------\n        private static LocalizabilityGroup LookupAndSetLocalizabilityAttribute(string input)\n        {\n            //\n            // For Localization.Attributes, values are seperated by spaces, e.g.\n            // $Content (Modifiable Readable)\n            // We are breaking the content and convert it to corresponding enum values.\n            //\n            LocalizabilityGroup attributeGroup = new LocalizabilityGroup();\n\n            StringBuilder builder = new StringBuilder();","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Globalization/LocalizationComments.cs#L174-L210","documentation":"ParsePropertyComments throws this FormatException when scanning ends with an unterminated construct: either a property name was read but no comment value followed, or buffered tokens remain without a complete PropertyName(Value) pair. Every entry in a Localization.Comments string must be a matched 'PropertyName(Comment)' pair.","triggerScenarios":"Input like 'Text(' with no closing ')', or a bare property name 'Text' with no parenthesized comment at all, when the Comments attribute is parsed (via pairs / LookupAndSetLocalizabilityAttribute).","commonSituations":"Truncated attribute values after a copy/paste, multi-line comment strings where the closing parenthesis was lost across line breaks, and hand-written [Localization.Comments] entries missing the value part.","solutions":["Close every comment with a matching ')' for its opening '('.","Give every listed property a parenthesized value; remove bare property names that have no comment.","Check for line-wrapping or trimming in resource files that dropped trailing parentheses.","Escape any literal '(' or ')' inside the comment text so nesting balance is correct."],"exampleFix":"// before\n[Localization.Comments]\nText(The window title\n// after\n[Localization.Comments]\nText(The window title)","handlingStrategy":"validation","validationCode":"static bool HasBalancedPairs(string v)\n{\n    if (string.IsNullOrWhiteSpace(v)) return false;\n    bool escaped = false; int open = 0;\n    foreach (char c in v)\n    {\n        if (escaped) { escaped = false; continue; }\n        if (c == '\\\\') { escaped = true; continue; }\n        if (c == '(') open++;\n        else if (c == ')') open--;\n    }\n    return open == 0 && !escaped;\n}","typeGuard":null,"tryCatchPattern":"try { ParsePropertyComments(input); } catch (FormatException) { log.Error($\"Unmatched Property(Comment) pair in '{input}'\"); }","preventionTips":["Close every '(' with ')'.","Check for truncation after copy/paste or line-wrapping in resx/baml sources.","Run the parser over all Comments attributes in CI before shipping localized builds."],"tags":["wpf","localization","format-exception","unbalanced-parentheses"],"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"}