{"record":{"id":"fac2d6f4efd7e6d6","repo":"abpframework/abp","slug":"incorrect-syntax-at-char-i-brackets-does-not-co","errorCode":null,"errorMessage":"Incorrect syntax at char {i}! Brackets does not containt any chars.","messagePattern":"Incorrect syntax at char (.+?)! Brackets does not containt any chars\\.","errorType":"exception","errorClass":"FormatException","httpStatus":null,"severity":"error","filePath":"framework/src/Volo.Abp.Core/Volo/Abp/Text/Formatting/FormatStringTokenizer.cs","lineNumber":46,"sourceCode":"\n                    if (currentText.Length > 0)\n                    {\n                        tokens.Add(new FormatStringToken(currentText.ToString(), FormatStringTokenType.ConstantText));\n                        currentText.Clear();\n                    }\n\n                    break;\n                case '}':\n                    if (!inDynamicValue)\n                    {\n                        throw new FormatException(\"Incorrect syntax at char \" + i + \"! These is no opening brackets for the closing bracket }.\");\n                    }\n\n                    inDynamicValue = false;\n\n                    if (currentText.Length <= 0)\n                    {\n                        throw new FormatException(\"Incorrect syntax at char \" + i + \"! Brackets does not containt any chars.\");\n                    }\n\n                    var dynamicValue = currentText.ToString();\n                    if (includeBracketsForDynamicValues)\n                    {\n                        dynamicValue = \"{\" + dynamicValue + \"}\";\n                    }\n\n                    tokens.Add(new FormatStringToken(dynamicValue, FormatStringTokenType.DynamicValue));\n                    currentText.Clear();\n\n                    break;\n                default:\n                    currentText.Append(c);\n                    break;\n            }\n        }\n","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/abpframework/abp/blob/7ed43b1931b9df46a50c0c59148a18645641d0df/framework/src/Volo.Abp.Core/Volo/Abp/Text/Formatting/FormatStringTokenizer.cs#L28-L64","documentation":"On encountering '}' that closes a dynamic segment, the tokenizer checks that currentText.Length > 0 (the segment had content between the braces). An empty pair '{}' leaves currentText empty, so it throws FormatException because a dynamic placeholder must name a value. Used by FormattedStringValueExtracter.Extract/IsMatch.","triggerScenarios":"Calling FormattedStringValueExtracter.Extract(str, format) with a format containing an empty placeholder: \"a{}b\", \"{}\", or \"name:{}\" (test case at FormattedStringTokenizer_Test.cs:16 tokenizes \"wrong {} format\").","commonSituations":"Template typos where the placeholder name was deleted but the braces remained; programmatically built formats where the name variable evaluated to empty; config-driven templates that forgot to supply the token name.","solutions":["Give the placeholder a name: \"a{value}b\" instead of \"a{}b\".","Validate that every brace pair in the format encloses at least one character before calling Extract.","Catch FormatException and treat malformed formats as a non-match when the source is untrusted."],"exampleFix":"// before: empty placeholder\nvar r = FormattedStringValueExtracter.Extract(input, \"order-{}.pdf\");\n// throws FormatException: Brackets does not containt any chars.\n\n// after: name the placeholder\nvar r = FormattedStringValueExtracter.Extract(input, \"order-{id}.pdf\");","handlingStrategy":"try-catch","validationCode":"static bool HasNoEmptyPlaceholders(string format)\n{\n    if (format.IsNullOrEmpty()) return true;\n    for (var i = 0; i < format.Length - 1; i++)\n    {\n        if (format[i] == '{' && format[i + 1] == '}') return false;\n    }\n    return true;\n}\n\nif (!HasNoEmptyPlaceholders(format)) { /* reject or fix template */ }","typeGuard":null,"tryCatchPattern":"try\n{\n    result = FormattedStringValueExtracter.Extract(str, format);\n}\ncatch (FormatException)\n{\n    result = new ExtractionResult(false);\n}","preventionTips":["When constructing formats from variables, assert the name is non-empty before emitting braces.","Validate templates at config load with a cheap '{}' scan.","Unit-test each template against representative inputs.","Keep a single source of truth for format strings so empty-placeholder typos are caught in review."],"tags":["formatting","format-string","parsing","tokenization","formatted-string"],"backgroundTag":null,"analyzedSha":"7ed43b1931b9df46a50c0c59148a18645641d0df","analyzedAt":"2026-08-13T16:26:11.351Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}