abpframework/abp · error · FormatException

Incorrect syntax at char {i}! Brackets does not containt any

Error message

Incorrect syntax at char {i}! Brackets does not containt any chars.

What it means

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.

Source

Thrown at framework/src/Volo.Abp.Core/Volo/Abp/Text/Formatting/FormatStringTokenizer.cs:46

                    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();

                    break;
                default:
                    currentText.Append(c);
                    break;
            }
        }

View on GitHub (pinned to 7ed43b1931)

Solutions

  1. Give the placeholder a name: "a{value}b" instead of "a{}b".
  2. Validate that every brace pair in the format encloses at least one character before calling Extract.
  3. Catch FormatException and treat malformed formats as a non-match when the source is untrusted.

Example fix

// before: empty placeholder
var r = FormattedStringValueExtracter.Extract(input, "order-{}.pdf");
// throws FormatException: Brackets does not containt any chars.

// after: name the placeholder
var r = FormattedStringValueExtracter.Extract(input, "order-{id}.pdf");
Defensive patterns

Strategy: try-catch

Validate before calling

static bool HasNoEmptyPlaceholders(string format)
{
    if (format.IsNullOrEmpty()) return true;
    for (var i = 0; i < format.Length - 1; i++)
    {
        if (format[i] == '{' && format[i + 1] == '}') return false;
    }
    return true;
}

if (!HasNoEmptyPlaceholders(format)) { /* reject or fix template */ }

Try / catch

try
{
    result = FormattedStringValueExtracter.Extract(str, format);
}
catch (FormatException)
{
    result = new ExtractionResult(false);
}

Prevention

When it happens

Trigger: 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").

Common situations: 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.

Related errors


AI-assisted analysis of abpframework/abp@7ed43b1931 (2026-08-13). Data as JSON: /api/errors/fac2d6f4efd7e6d6. Report an issue: GitHub.