quarkusio/quarkus · error · IllegalArgumentException

Invalid template ${template} Unmatched { braces

Error message

Invalid template ${template} Unmatched { braces

What it means

After successfully scanning the URI template, URITemplate checks bracesCount > 0: an unmatched '{' remains, so the constructor throws IllegalArgumentException("Invalid template " + template + " Unmatched { braces"). This happens when a literal '{' appears without a matching '}' or is nested incorrectly.

Source

Thrown at independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/mapping/URITemplate.java:125

                            bracesCount--;
                        }
                    }
                    break;
            }
        }
        switch (state) {
            case 0:
                if (sb.length() > 0) {
                    String literal = sb.toString();
                    stem = handlePossibleStem(components, stem, literal);
                }
                break;
            case 1:
            case 2:
                throw new IllegalArgumentException("Invalid template " + template);
        }
        if (bracesCount > 0) {
            throw new IllegalArgumentException("Invalid template " + template + " Unmatched { braces");
        }

        //coalesce the components
        //once we have a CUSTOM_REGEX everything goes out the window, so we need to turn the remainder of the
        //template into a single CUSTOM_REGEX
        List<String> groupAggregator = null;
        List<String> nameAggregator = null;
        StringBuilder regexAggregator = null;
        Iterator<TemplateComponent> it = components.iterator();
        while (it.hasNext()) {
            TemplateComponent component = it.next();

            if (component.type == Type.CUSTOM_REGEX && nameAggregator == null) {
                regexAggregator = new StringBuilder();
                groupAggregator = new ArrayList<>();
                nameAggregator = new ArrayList<>();
            }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Balance all braces: every '{' in the template must have a matching '}'
  2. For regex quantifiers inside custom patterns, verify the parser supports the nested-brace form or rewrite the pattern (e.g. [0-9]{2,3} inside {id:regex(...)}) and confirm nesting is counted correctly
  3. Escape or remove stray literal '{' from the path

Example fix

// before
@Path("/items/{id") // or "/items/{id:{2}" with unbalanced braces

// after
@Path("/items/{id:regex("[0-9]{2,3}")}")
Defensive patterns

Strategy: validation

Validate before calling

// every '{' must be closed before template use
int depth = 0;
for (char c : template.toCharArray()) {
    if (c == '{') depth++;
    if (c == '}') depth--;
    if (depth < 0) throw new IllegalArgumentException("Unmatched } in: " + template);
}
if (depth != 0) throw new IllegalArgumentException("Unmatched { in: " + template);

Try / catch

try {
    new URITemplate(template);
} catch (IllegalArgumentException e) {
    if (e.getMessage() != null && e.getMessage().contains("Unmatched { braces")) {
        throw new IllegalStateException("Fix unbalanced '{' in path template: " + template, e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Templates containing '{' that never closes, or nested braces like "/a/{x/{y}}" or a stray '{' in a literal segment — bracesCount incremented on '{' but never decremented to zero.

Common situations: Regex patterns inside parameters that themselves contain '{' (quantifiers like {2,3}) without the parser's expected nesting; accidental double braces from format strings; concatenating partial templates each missing braces.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/4ba5fce96914cd36. Report an issue: GitHub.