abpframework/abp · error · FormatException
Incorrect syntax at char {i}! These is no opening brackets f
Error message
Incorrect syntax at char {i}! These is no opening brackets for the closing bracket }. What it means
While tokenizing a format string, a '}' is read when inDynamicValue is false (no preceding '{' opened a dynamic segment). The tokenizer treats '}' exclusively as the close of a dynamic value, so a stray closing brace with no matching open is a syntax error and throws FormatException. Used internally by FormattedStringValueExtracter.Extract/IsMatch.
Source
Thrown at framework/src/Volo.Abp.Core/Volo/Abp/Text/Formatting/FormatStringTokenizer.cs:39
case '{':
if (inDynamicValue)
{
throw new FormatException("Incorrect syntax at char " + i + "! format string can not contain nested dynamic value expression!");
}
inDynamicValue = true;
if (currentText.Length > 0)
{
tokens.Add(new FormatStringToken(currentText.ToString(), FormatStringTokenType.ConstantText));
currentText.Clear();
}
break;
case '}':
if (!inDynamicValue)
{
throw new FormatException("Incorrect syntax at char " + i + "! These is no opening brackets for the closing bracket }.");
}
inDynamicValue = false;
if (currentText.Length <= 0)
{
throw new FormatException("Incorrect syntax at char " + i + "! Brackets does not containt any chars.");
}
var dynamicValue = currentText.ToString();
if (includeBracketsForDynamicValues)
{
dynamicValue = "{" + dynamicValue + "}";
}
tokens.Add(new FormatStringToken(dynamicValue, FormatStringTokenType.DynamicValue));
currentText.Clear();
View on GitHub (pinned to 7ed43b1931)
Solutions
- Remove the stray '}' or pair it with a matching '{...}' dynamic segment.
- Add a brace-balance validation pass over the format before calling Extract and reject/sanitize unbalanced templates.
- Catch FormatException around Extract when the format is user-supplied and treat it as a non-match.
Example fix
// before: stray closing brace, no opening brace
var r = FormattedStringValueExtracter.Extract(input, "user} profile");
// throws FormatException: no opening bracket for the closing }
// after: drop the brace, or open a proper dynamic segment
var r = FormattedStringValueExtracter.Extract(input, "user profile");
// or: var r = FormattedStringValueExtracter.Extract(input, "{name} profile"); Defensive patterns
Strategy: try-catch
Validate before calling
static bool HasBalancedBraces(string format)
{
if (format.IsNullOrEmpty()) return true;
var depth = 0;
foreach (var c in format)
{
if (c == '{') depth++;
else if (c == '}')
{
if (depth == 0) return false; // stray closing brace
depth--;
}
}
return depth == 0;
}
if (!HasBalancedBraces(format)) { /* reject template */ } Try / catch
try
{
result = FormattedStringValueExtracter.Extract(str, format);
}
catch (FormatException)
{
result = new ExtractionResult(false); // treat malformed format as non-match
} Prevention
- Run a brace-balance check on every template when it is loaded from config.
- Never build formats by naive concatenation of fragments that may each contain braces.
- Unit-test format templates with sample inputs before shipping.
- Keep format strings in constants so typos surface at compile/review time.
When it happens
Trigger: Calling FormattedStringValueExtracter.Extract(str, format) with a format whose first brace character is '}': "} text", "a}b", or "name}suffix". Any '}' encountered before any '{' triggers it (test case at FormattedStringTokenizer_Test.cs:15 tokenizes "} wrong format").
Common situations: Config or template strings with an unbalanced closing brace (typo, truncated copy-paste); JSON/code-snippet templates pasted as formats where '}' survived from an object literal; format strings built by concatenation that dropped the opening '{'.
Related errors
- Incorrect syntax at char {i}! format string can not contain
- Incorrect syntax at char {i}! Brackets does not containt any
- There is no closing } char for an opened { char.
- Should specify an option name after '--' prefix!
- Should specify an option name after '-' prefix!
AI-assisted analysis of abpframework/abp@7ed43b1931 (2026-08-13).
Data as JSON: /api/errors/5b41a8368d7327a3.
Report an issue: GitHub.